bizz84 / SwiftyStoreKit

Lightweight In App Purchases Swift framework for iOS 8.0+, tvOS 9.0+ and macOS 10.10+ ⛺
MIT License
6.56k stars 797 forks source link

Verification of the receipt on server side (non-atomic purchase) #153

Closed kostasoft closed 7 years ago

kostasoft commented 7 years ago

Platform

In app purchase type

Environment

Version

ℹ 0.8.2

Related issues

ℹ Please replace this with references to similar issues (either open or already closed).

Report

Issue summary

ℹ Hello!

Whether I transfer the correct data to the server for sending for the server of Apple?

My code (client side):

SwiftyStoreKit.purchaseProduct(productName, atomically: false) { result in
            switch result {
            case .success(let product):
                if let receiptData = SwiftyStoreKit.localReceiptData {
                    let receipt = receiptData.base64EncodedString()
                    self.sendReceipt(receipt: receipt)  //Send to my server
                }
                break
            case .error(let error):
                self.showAlert(title: "ERROR".localized, message: error.localizedDescription, completion: { (isPresed) in })
                break
            }
        }

PHP script (server side)

<?php
$sandbox = $_REQUEST['sandbox'];
$receipt = $_REQUEST['receipt'];

if (!isset($receipt)) {
    exit("Data lost");
}

$url = 'https://buy.itunes.apple.com/verifyReceipt';
if (isset($sandbox) && $sandbox) {
    $url = 'https://sandbox.itunes.apple.com/verifyReceipt';
}

$json = array();
$json['receipt-data'] = $receipt;
$post = json_encode($json);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://buy.itunes.apple.com/verifyReceipt");
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);

$result=curl_exec ($ch);
curl_close ($ch);

$result = json_decode($result,true);

$response = array();
$response["response"] = $result;

if ($result["status"] == 0) {
    $response["message"] = "Payment verified";
    $response["success"] = "1";
} else {
    $response["message"] = "Payment not verified";
    $response["success"] = "0";
}
echo json_encode($response, JSON_PRETTY_PRINT);

What did you expect to happen

ℹ I expect that the server of Apple will confirm perfect purchase, having returned the status 0

What happened instead

ℹ Apple server returned:

kostasoft commented 7 years ago

Sorry. Problem in a php-script. Where - yet hasn't found, but it has no relation to SwiftyStoreKit any more

PS: Php-script not correctly created data from: json_encode (array ('receipt-data' => $base64EncodedReceipt)) I have created it on application-side and began to transfer to a script in coded form (base64) in POST inquiry. Everything has earned.

bizz84 commented 7 years ago

Closing this as it's not related to SwiftyStoreKit.

contreras2004 commented 7 years ago

Did you manage to solve this? I am trying to use this library to verify the receipt but I had no success https://github.com/aporat/store-receipt-validator It always shows me

Receipt is not valid.
Receipt result code = 21002
iwasrobbed commented 7 years ago

@contreras2004 See the error codes here: https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

21002 | The data in the receipt-data property was malformed or missing.

Check the server is receiving valid data

contreras2004 commented 7 years ago

Yea thanks. I managed to solve this. I was trying to verify a renewable subscription receipt and I forgot to add the secret

jbarros35 commented 3 years ago

SwiftyStoreKit.ReceiptStatus.malformedOrMissingData