Post

Replies

Boosts

Views

Activity

Subscription Offer generate signature with PHP
is I am trying to do this https://developer.apple.com/documentation/storekit/in-app_purchase/generating_a_signature_for_subscription_offers in PHP.I am wondering if I did the signature generation properly. It's really specific to PHP but maybe someone can help:class Key_offer { var $appBundleId; var $keyIdentifier; var $productIdentifier; var $offerIdentifier; var $applicationUsername; var $nonce; var $timestamp; function __construct() { // Setting Data $this->appBundleId = 'bundle_id'; $this->keyIdentifier = 'XXXXXXXXXX'; $this->productIdentifier = $_POST["productIdentifier"]; $this->offerIdentifier = $_POST["offerIdentifier"]; $this->applicationUsername = $_POST["usernameHash"]; $this->nonce = strtolower( $this->gen_uuid() ); $this->timestamp = time() * 1000; } function rsa_sign($policy, $private_key_filename) { $signature = ""; // load the private key $fp = fopen($private_key_filename, "r"); $priv_key = fread($fp, 8192); fclose($fp); $pkeyid = openssl_get_privatekey($priv_key); // compute signature openssl_sign($policy, $signature, $pkeyid); // free the key from memory openssl_free_key($pkeyid); return $signature; } function gen_uuid() { return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', // 32 bits for "time_low" mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), // 16 bits for "time_mid" mt_rand( 0, 0xffff ), // 16 bits for "time_hi_and_version", // four most significant bits holds version number 4 mt_rand( 0, 0x0fff ) | 0x4000, // 16 bits, 8 bits for "clk_seq_hi_res", // 8 bits for "clk_seq_low", // two most significant bits holds zero and one for variant DCE1.1 mt_rand( 0, 0x3fff ) | 0x8000, // 48 bits for "node" mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) ); } function get() { $text = utf8_encode($this->appBundleId.'\u2063'.$this->keyIdentifier.'\u2063'.$this->productIdentifier.'\u2063'.$this->offerIdentifier.'\u2063'.$this->applicationUsername.'\u2063'.$this->nonce.'\u2063'.$this->timestamp); $signature0 = $this->rsa_sign($text, "key.pem"); $signature = hash('sha256', $signature0); $array = array( 'lowUUid' => $this->nonce, 'timeStump' => $this->timestamp, 'identifier' => $this->offerIdentifier, 'keyid' => $this->keyIdentifier, 'signature' => base64_encode($signature) ); return json_encode($array); } } $obj = new Key_offer(); echo $obj->get(); ?>And in the app (Swift) preparing Offer =>public func prepareOffer(usernameHash: String, productIdentifier: String, offerIdentifier: String, completion: @escaping (SKPaymentDiscount?) -> Void) { let config = URLSessionConfiguration.default let session = URLSession.init(configuration: config) // configuration session let url = URL(string: "http://192.168.2.100/Key_Offer/genera_class.php")! var request = URLRequest(url: url) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" let postString = "usernameHash=\(usernameHash)&productIdentifier=\(productIdentifier)&offerIdentifier=\(offerIdentifier)" request.httpBody = postString.data(using: .utf8) let task = session.dataTask(with: request) { (data, response, error) in guard let data = data, error == nil else { // check for fundamental networking error print("Send POST error= ", error ?? 1) DispatchQueue.main.async { completion(nil) } return } if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors print("statusCode should be 200, but is \(httpStatus.statusCode)") print("Response = \(String(describing: response))") DispatchQueue.main.async { completion(nil) } } // DA DATA TO JSON CONVERSION let decoder = JSONDecoder.init() do { let post_response = try decoder.decode(SkProd.self, from: data) print(post_response) DispatchQueue.main.async { let lowUUid = UUID.init(uuidString: post_response.lowUUid)! let timeStump = NSNumber.init(value: post_response.timeStump) let identifier = post_response.identifier let keyID = post_response.keyid let signature = post_response.signature let paymentDiscount = SKPaymentDiscount(identifier: identifier, keyIdentifier: keyID, nonce: lowUUid, signature: signature, timestamp: timeStump) // genera la firma per poter creare l'offerta // completed with Success, return a SKPaymentDiscount completion(paymentDiscount) } } catch let error { print("Errore nella conversione del json API Login", error) DispatchQueue.main.async { completion(nil) } } } task.resume() }and this is the Purchase function to purchase the offer =>publicfunc buyProduct(product: SKProduct, usernameHash: String, discountOffer: SKProductDiscount) { let payment = SKMutablePayment.init(product: product) payment.applicationUsername = usernameHash // Add the offer to the payment. print(usernameHash) print(product.productIdentifier) print(discountOffer.identifier!) // REQUEST signature from Server self.prepareOffer(usernameHash:usernameHash, productIdentifier: product.productIdentifier, offerIdentifier: discountOffer.identifier!) { (prodottoDiscount) in if(prodottoDiscount != nil) { // set PaymentDiscount Product payment.paymentDiscount = prodottoDiscount! // Add the payment to the queue for purchase. SKPaymentQueue.default().add(payment) } } }And this is the mistake I get, I hope someone can help me find the error.https://www.tuunes.org/screen.png
2
0
2.0k
Apr ’19