Category: php

  • Decode Apple Receipt

    Decode Apple Receipt

    Decode Apple Receipt

    Verify with the server-side click here

    /**
     * ***********************************************************************
     *  SMINRANA CONFIDENTIAL
     *   __________________
     *
     * Copyright 2020  SMINRANA
     * All Rights Reserved.
     *
     * NOTICE:  All information contained herein is, and remains
     * the property of SMINRANA and its suppliers,
     * if any.  The intellectual and technical concepts contained
     * herein are proprietary to SMINRANA
     * and its suppliers and may be covered by U.S. and Foreign Patents,
     * patents in process, and are protected by trade secret or copyright law.
     * Dissemination of this information or reproduction of this material
     * is strictly forbidden unless prior written permission is obtained
     * from SMINRANA.
     * www.sminrana.com
     *
     */
    
    import SwiftUI
    import StoreKit
    import Combine
    
    class AppStorageManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    
        @AppStorage("username") var username: String = ""
        @AppStorage("password") var password: String = ""
        
        override init() {
            super.init()
            
            SKPaymentQueue.default().add(self)
        }
        
        @Published var products = [SKProduct]()
        
        func getProdcut(indetifiers: [String]) {
            print("Start requesting products ...")
            let request = SKProductsRequest(productIdentifiers: Set(indetifiers))
            request.delegate = self
            request.start()
        }
        
    
        // SKProductsRequestDelegate
    
        func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
            print("Did receive response \(response.products)")
                    
            if !response.products.isEmpty {
                for fetchedProduct in response.products {
                    DispatchQueue.main.async {
                        self.products.append(fetchedProduct)
                    }
                }
            }
            
            for invalidIdentifier in response.invalidProductIdentifiers {
                print("Invalid identifiers found: \(invalidIdentifier)")
            }
        }
        
        func request(_ request: SKRequest, didFailWithError error: Error) {
            print("Request did fail: \(error)")
        }
        
    
        // Transaction
        
        @Published var transactionState: SKPaymentTransactionState?
        
        func purchaseProduct(product: SKProduct) {
            if SKPaymentQueue.canMakePayments() {
                let payment = SKPayment(product: product)
                SKPaymentQueue.default().add(payment)
            } else {
                print("User can't make payment.")
            }
        }
    
        func restorePurchase() {
            SKPaymentQueue.default().restoreCompletedTransactions()
        }
        
        struct PaymentReceiptResponseModel: Codable {
            var status: Int
            var email: String?
            var password: String?
            var message: String?
        }
        
        // SKPaymentTransactionObserver
    
    
        // This gets called when transaction purchased by user
        func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
            for transaction in transactions {
                switch transaction.transactionState {
                case .purchasing:
                    self.transactionState = .purchasing
                case .purchased:
                    print("===============Purchased================")
                    UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
    
                    if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
                        FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
    
                        do {
                            let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
                            let receiptString = receiptData.base64EncodedString(options: [])
                            
                           // Send receiptString to server for further verification
                        }
                        catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
                    }
    
                case .restored:
                    UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
    
                    queue.finishTransaction(transaction)
                    print("==================RESTORED State=============")
                    self.transactionState = .restored
                case .failed, .deferred:
                    print("Payment Queue Error: \(String(describing: transaction.error))")
                    queue.finishTransaction(transaction)
                    self.transactionState = .failed
                default:
                    print(">>>> something else")
                    queue.finishTransaction(transaction)
                }
            }
        }
        
        // This gets called when a transaction restored by user
        func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
            print("===============Restored================")
            if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
                FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
    
                do {
                    let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
                    let receiptString = receiptData.base64EncodedString(options: [])
                    
                    // Send receiptString to server for further verification
                }
                catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
            }
        }
        
      
    }
    
    Spread the love
  • Laravel Sanctum with JavaScript

    Laravel Sanctum with JavaScript

    Laravel Sanctum with JavaScript

    Laravel Sanctum is a package for Laravel that provides a lightweight authentication system for single page applications (SPAs), mobile applications, and simple token-based APIs. It allows for the generation of API tokens that can be used to authenticate requests to your Laravel application without the need for a traditional login process. This can be useful for applications that need to make API requests to your Laravel application from a frontend JavaScript framework like React or Vue.js, or for mobile applications that need to authenticate users without a server-side session.

    How to integrate in JavaScript

    1. Install the Laravel Sanctum package by running the following command in your terminal:
    composer require laravel/sanctum

    2. Publish the package’s configuration and migration files by running the following command:

    php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

    3. In your config/auth.php file, make sure the driver option for the api guard is set to sanctum.

    4. In your .env file, make sure the SANCTUM_STATEFUL_DOMAINS variable is set to a comma-separated list of domains that should be able to make stateful requests (requests that maintain a user session) to your application.

    5. Run the migration to create the necessary database tables by running the following command:

    php artisan migrate

    6. In your frontend JavaScript code, you can use Laravel Sanctum’s JavaScript library to make API requests to your Laravel application and authenticate them using an API token. To do this, you will need to first install the library using npm or yarn:

    npm install @laravel/sanctum

    7. In your JavaScript code, you can then use the createToken method to create a new API token for a given user, and the authenticate method to attach the token to subsequent API requests:

    import { createToken, authenticate } from '@laravel/sanctum';
    
    // Create a new API token for the authenticated user
    createToken('user-id')
        .then(response => {
            // Attach the token to subsequent API requests
            authenticate(response.token);
        });
    

    8. In your Laravel routes, you can use the auth:sanctum middleware to protect routes that require authentication:

    Route::get('/profile', function () {
        // Only authenticated users with a valid API token can access this route
    })->middleware('auth:sanctum');
    

    You can also check the Laravel Sanctum documentation for more detailed instructions and additional features.

    Read More About Laravel Sanctum

    Spread the love
  • Laravel Sanctum Tutorial Step by Step

    Laravel Sanctum Tutorial Step by Step

    Laravel Sanctum provides a featherweight authentication system for single-page applications, mobile applications, and simple, token-based APIs. Sanctum allows each user of your application to generate multiple API tokens for their account. These tokens may be granted abilities/scopes which specify which actions the tokens are allowed to perform.

    Installation

    composer require laravel/sanctum and composer update

    Next, you should publish the Sanctum configuration and migration files using the vendor:publish Artisan command. 

    php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
    php artisan migrate 

    You can also use following sql for creating table, if there is a problem to run migrate command.

    CREATE TABLE `personal_access_tokens` (
       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
       `tokenable_type` varchar(255) NOT NULL,
       `tokenable_id` bigint(20) unsigned NOT NULL,
       `name` varchar(255) NOT NULL,
       `token` varchar(64) NOT NULL,
       `abilities` text DEFAULT NULL,
       `last_used_at` timestamp NULL DEFAULT NULL,
       `created_at` timestamp NULL DEFAULT NULL,
       `updated_at` timestamp NULL DEFAULT NULL,
       PRIMARY KEY (`id`),
       UNIQUE KEY `personal_access_tokens_token_unique` (`token`),
       KEY `personal_access_tokens_tokenable_type_tokenable_id_index` (`tokenable_type`,`tokenable_id`)
     ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8

    Next, if you plan to utilize Sanctum to authenticate an SPA, you should add Sanctum’s middleware to your api middleware group within your application’s app/Http/Kernel.php file:

    'api' => [
                'throttle:60,1',
                'bindings',
                \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            ],
    Laravel Sanctum Tutorial Step by Step

    Download source code

    Spread the love