j3k0 / cordova-plugin-purchase

In-App Purchase for Cordova on iOS, Android and Windows
https://purchase.cordova.fovea.cc
1.3k stars 537 forks source link

[IOS] What response is expected from the validator? #1252

Closed vesper8 closed 3 years ago

vesper8 commented 3 years ago

I'm using my own validator which I specify like so:

        // Setup the receipt validator service.
        window.store.validator = `${this.$api}/api/v1/iap/${process.env.CORDOVA_PLATFORM}/validate`;

Then on my backend I setup a POST endpoint.

I receive the payload, grab the appStoreReceipt from the transaction, perform the validation using https://github.com/imdhemy/laravel-in-app-purchases

Then if the receipt passes validation, I'm currently just returning a 200 OK response.

And yet I am getting Transaction verification failed on the client.

I get that you really want us to use your fovea.cc service, but my client has asked that we roll our own and I just want to get that working, there is unfortunately no documentation (that I can find) at all on how to use the validator.

I understand that you don't want to document how to perform all the server-side verification and that's fine, I just want to know why I am still getting Transaction verification failed even though the endpoint is returning a success response (200 OK).

Any insight on how to get this working would be appreciated. Many thanks!

vesper8 commented 3 years ago

Ah nevermind I think.. I was able to locate some documentation on Github

https://github.com/j3k0/cordova-plugin-purchase/blob/master/doc/api.md#validator

I will read more on that and give that a try.

jonah-butler commented 2 years ago

I'm struggling with this receipt validation with my custom validator right now. That documentation helped somewhat, but I can't get past this Xcode log: DEBUG: validator failed, response: "Error: 0"

I setup the validator as so - this is a lambda service: InAppPurchase2.validator = lambdaValidationUrl;

And all that's happening in the lambda function, is that I'm passing the appStoreReceipt along with the sharedSecret and exclude-old-transactions keys and values as a payload to Apple's receipt validation url: 'https://sandbox.itunes.apple.com/verifyReceipt'

I get a healthy response from the lambda fetch, which logs the receipt object that contains all the in_app data about the purchase.

But I'm not sure I'm returning the right object from the Ajax call happening in this plugin's validator.js file. Assuming that's what is causing this Error 0 log.

Right now, I'm returning it like this:

return {
    ok: true,
    data: JSON.stringify(data)
  };

Where data in this situation is this object:

  {
    "receipt": {
      "receipt_type": "ProductionSandbox",
      "adam_id": 0,
      "app_item_id": 0,
      "bundle_id": "com.mybundle.iap",
      "application_version": "1",
      "download_id": 0,
      "version_external_identifier": 0,
      "receipt_creation_date": "2022-03-25 18:20:43 Etc/GMT",
      "receipt_creation_date_ms": "1648232443000",
      "receipt_creation_date_pst": "2022-03-25 11:20:43 America/Los_Angeles",
      "request_date": "2022-03-29 14:37:20 Etc/GMT",
      "request_date_ms": "1648564640724",
      "request_date_pst": "2022-03-29 07:37:20 America/Los_Angeles",
      "original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
      "original_purchase_date_ms": "1375340400000",
      "original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
      "original_application_version": "1.0",
      "in_app": [
        {
          "quantity": "1",
          "product_id": "ultra1",
          "transaction_id": "2000000018696803",
          "original_transaction_id": "2000000018696803",
          "purchase_date": "2022-03-25 18:20:43 Etc/GMT",
          "purchase_date_ms": "1648232443000",
          "purchase_date_pst": "2022-03-25 11:20:43 America/Los_Angeles",
          "original_purchase_date": "2022-03-25 18:20:43 Etc/GMT",
          "original_purchase_date_ms": "1648232443000",
          "original_purchase_date_pst": "2022-03-25 11:20:43 America/Los_Angeles",
          "is_trial_period": "false",
          "in_app_ownership_type": "PURCHASED"
        }
      ]
    },
    "environment": "Sandbox",
    "status": 0
  }

Do you have any recommendations for the custom validator setup or see anything obvious about this setup that isn't correct? Appreciate it.