I'm in the process of implementing InApp purchases (subscriptions) with Huawei In App SDK.
Everything's good except token verification against Huawei's servers.
My code is similar to that here: https://developer.huawei.com/consumer/en/doc/development/HMS-References/iap-api-order-service-purchase-token-verification-v4
I'm using an access token which is obtained like so: https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/38054564 - the same code to obtain access tokens already works with Huawei Push SDK by the way.
For verification, my code sends requests to https://orders-dre.iap.hicloud.com/applications/purchases/tokens/verify with this data:
{
"purchaseToken":"00000175799be0e659fc74cb06...5.8.5650",
"productId":"annual"
}
The response comes back as:
{"responseCode":"6","responseMessage":"rights invalid"}
The FAQ here https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/iap-FAQ recommends:
"You are advised to check whether the app ID used for obtaining AccessToken is the same as the app ID associated with purchaseToken in the request".
Now I only have one project / one set of Client ID / Client Secret, so it matches the app ID, by definition.
What could be wrong?
PS - this is happening with a test subscription, i.e. purchased by a user account that's set up as a test account.
According to the code part you provided, you are using Purchase Token Verification for the Order Service, and you should use API for Verifying the Purchase Token for the Subscription Service.
Purchase Token Verification for the Order Service applies only to non-subscription purchases. It is used to verify the purchase token in the payment result sent from the Huawei IAP server to ensure payment accuracy.
API for Verifying the Purchase Token for the Subscription Service applies only to subscriptions. It is used to check whether a product has been successfully purchased and is within the validity period.
Verifying the Purchase Token for the Subscription Service:
Parameter: subscriptionId;purchaseToken
RequestUrl: {rootUrl}/sub/applications/v2/purchases/get
rootURL:
China: https://subscr-drcn.iap.hicloud.com
Germany: https://subscr-dre.iap.hicloud.com
Singapore: https://subscr-dra.iap.hicloud.com
Russia: https://subscr-drru.iap.hicloud.com
AppTouch site of Germany: https://subscr-at-dre.iap.dbankcloud.com
Related
I am trying to validate my purchases(for now consumables). For this reason i am developing small server app. I found out this git package hms iap server demo
In DemoCofig script has need 2 variable
ClientId, ClientSecret. I getted from app gallery connect dashboard from Project Settings->App Information.
After pruchasing i am writing the console my purchase token which i getted InAppPurchaseData.PurchaseToken.
and i am requesting from my server to IAP Server. It always returning:
"{\"responseCode\":\"6\",\"responseMessage\":\"Token is expired or invalid\"}"
Purchasing job is working on SandBox(Test), I am trying to reach : https://orders-at-dre.iap.dbankcloud.com.
I am not clearly understand which token is expired or invalid ? Access Token or my purchase token ?
"{\"responseCode\":\"6\",\"responseMessage\":\"Token is expired or invalid\"}"
This interface prompts that the token is invalid or expired. Generally, the token is an AccessToken (the validity period is 1 hour, AT for short). The validity period of the purchaseToken is 30 days. (There is also a possibility of expiration, but it is much less likely than the former).
The possible causes are as follows:
The AT has expired. In this case, the AT needs to be obtained again (high probability).
API for Obtaining an App-Level Access Token
Invalid AT format (medium probability)
Ensure that the format of the request body is correct when the AT is used as the request body.
The authentication information is specified based on the request header. The details are as follows:
Authentication information is specified based on the request header:
App-level access token: Authorization: Basic Base64(APPAT:atvalue)
Example: The app-level access token is thisIsAppAtValue, then APPAT:atvalue is APPAT:thisIsAppAtValue.
Therefore, replace APPAT:atvalue in Base64(APPAT:atvalue) with "APPAT:thisIsAppAtValue" to generate value QVBQQVQ6dGhpc0lzQXBwQXRWYWx1ZQ==.
The value of Authorization in the request header is as follows: Basic QVBQQVQ6dGhpc0lzQXBwQXRWYWx1ZQ==
For details check this docs.
The purchaseToken does not match the appID (low probability).
Site request error (low probability)
You can also refer to this forum similar questions, but it is in Chinese, you can translate it.
While using Unity 2020.3.9f1 and Unity IAP 3.2.1 I can send the initial subscription via a regular https request to my Spring backend and receive the user information from backend auth + purchase token via the request. I can then insert the expiry date (which I query from Google API using AndroidPublisher and the token) to my database and give premium features to the given user for that time period.
When the subscription is about to renew, I need to update the users premium feature expiry date in the database accordingly.
I already found out, that I can receive this renewal information, even if the client is not active, via Google Cloud Pub/Sub by linking it with the apps monetization. The backend then receives a purchase token, but this time there is no more user information since the request was not issued through a client/server request.
I also figured out that there is/was a developer payload to use for that purpose. My question is how I can add this to the subscription to link renewal subscription notifications to a certain user on receiving renewal subscription notifications. I do not really want to add a new index on a (at least in test mode always unique) purchase token to my database if I do not have to.
I use Firebase Auth in my app - can I make use of that in any way?
I'm in the process of migrating our software, which makes requests on behalf of merchants to PayPal using the PayPal SOAP API, to the PayPal REST API infrastructure.
I'm using the Client ID / Secret of my PayPal developer account to get a Bearer token from the Sandbox, using https://api.sandbox.paypal.com/v1/oauth2/token.
Then I'm doing a call to https://api.sandbox.paypal.com/v2/checkout/orders, using our the bearer token just got, to make requests on behalf of a merchant. I'm using the PayPal-Auth-Assertion header with the following (encoded) JWT-Token:
Header:
{
"typ": "JWT",
"alg": "HS256"
}
Body: {
"email": "[merchant e-mail]",
"iss": "[my client id]"
}
The "merchant e-mail" is one of the sandbox accounts I opened in https://developer.paypal.com/developer/accounts/
In return I get a (400) Bad Request {"error":"invalid_request","error_description":"No permissions to set target_client_id"}.
It seems like there must be an additional step for the sandbox account to grant permissions to the developer account. For the SOAP API, I could add the user name of a 3rd party in the following screen . Then I could use the same username as header value for X-PAYPAL-SECURITY-USERID. However, I cannot seem to link the sandbox account in the same way, because there is no "third party username" for the main account (the one I'm getting the Client ID from).
What exactly has to be configured to allow these types of 3rd party calls for REST API?
I'm using the PayPal-Auth-Assertion header with the following (encoded) JWT-Token:
You need to be a PayPal partner to be using that type of functionality. Contact PayPal if you want to be a partner.
If you want to use their generally-accessible APIs, you have two options.
Have every merchant create their own REST API App via https://www.paypal.com/signin?intent=developer&returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Fapplications , and copy paste their live client ID and secret into your configuration. This is the best solution, and it is the solution you should pursue.
Use the payee object: https://developer.paypal.com/docs/checkout/integration-features/custom-payee/ , which gives you less control (cannot capture authorizations or issue refunds, for example)
I have a app on uber with request_receipt scope avaiable
But when i trying to get a request receipt with a token created in my app i got Forbidden error.
Others endpoints (map, product, history...) are ok.
My authentication request is fine too and return:
{
"expires_in"=>2592000,
"token_type"=>"Bearer",
"refresh_token"=>"[...]",
"last_authenticated"=>0,
"scope"=>"history profile history_lite places ride_widgets all_trips request_receipt",
"user_id"=>"[...]"
}
I made this requests on app and get same error.
You can only access trips that were initiated through your own Uber integration. For instance, if you book a ride through the Uber app and take that request id, you won't be able to access the details of that ride. Here's what the docs state:
The receipt endpoint will only provide receipts for ride requests originating from your application. It is not currently possibly to receive receipt data for all trips.
I'm developing web-service, where one users (companies) can receive payments directly from another (company's customers). Currently company need to enter its PayPal username, password and signature to receive payments via express checkout api. Is it normal, that users (companies in my case) will enter their PayPal credentials on remote site or it's secure information? I can't find any information about it. But i found, that some services work in the same way:
http://www.getharvest.com/help/invoices-and-estimates/online-payment-and-gateways/paypal-website-payments-pro
http://support.getresponse.com/faq/how-find-api-login-data-paypal
help.wildapricot.com/display/DOC/PayPal+Payments+Pro
Also i found another way for receiving direct payments - generate button (on the PayPal site or manually), where you need only PayPal email of seller. What the differences between these methods, its advantages and disadvantages?
Yes, they are considered private. Since it grants you access to all API operations, it can also be used to empty your PayPal account.
What I would recommend instead of collecting API credentials, is to use 'third-party permissions'.
This means initially requesting permission from the account holder via a pop-up dialog. Once granted, you'll receive an access token. This access token can then be included in the HTTP header of your API calls to make calls on behalf of the customer.
Your users can either manually grant permissions to you (they'll need to log into their PayPal account and navigate to the right section within their Profile), or, if you want to make it easier, you can implement the 'Permissions API'.
I would suggest taking a look at https://developer.paypal.com/webapps/developer/docs/classic/products/permissions/ for more information.
To get started, sign up for an 'application' with PayPal via https://apps.paypal.com/.
Ensure you request access to the Permissions Service and receive an Application ID.
This will be the AppID for the Live environment. For Sandbox, you can use APP-80W284485P519543T.