IsValidateApplePurchase
public BackendReturnObject IsValidateApplePurchase(string receipt, string receiptDescription);
Some countries use commas (,
) instead of periods (.
) to represent decimal numbers.\
In such countries, the iapPrice value provided by each store may also include commas (,
).\
Since BACKND's receipt validation can only process numeric data, using iapPrice values that include commas (,
) as-is may cause the amount to be processed incorrectly as 0.\
Please replace commas(,
) with periods (.
) in iapPrice data before use.\
Invalid special characters
Special Character | Name |
---|---|
' | Single quotation mark |
\ | Backslash |
Valid special characters
Special Character | Name |
---|---|
. | Period |
, | Comma |
" | Double quotation mark |
() | Parentheses |
! | Exclamation mark |
? | Question mark |
~ | Tilde |
@ | At sign |
* | Asterisk |
+ | Plus |
- | Hyphen |
/ | Slash |
If you are using special characters that are not listed above, manually check that the receipt verification works properly before applying.
Parameters
Value | Type | Description |
---|---|---|
receipt | string | Purchasing.PurchaseEventArgs.purchasedProduct.receipt |
receiptDescription | string | Additional details to be stored |
Description
IStoreListener.ProcessPurchase() in the IAP service supported by Unity accepts the receipt for the purchased product and verifies it via the BACKND server.
- BACKND verifies the validity of the receipt itself and the purchased productId.
- You must be logged in to BACKND to use its receipt verification function.
- Apple receipt verification supports normal product receipts only. It does not support subscription product receipts.
To verify Apple receipts, Apple Console must be configured. For more information, please refer to the Apple Payment Console Settings documentation.
Display amount of purchase (optional)
To display the transaction price in the receipt verification section of the BACKND Console, you must include the parameters iapPrice and iapCurrency.
private void GetCheckGoogleReceiptWithPrice(PurchaseEventArgs purchaseEvent)
{
string receiptToken = purchaseEvent.purchasedProduct.receipt;
var bro = Backend.Receipt.IsValidateApplePurchase(
json: receiptToken,
receiptDescription: "Purchased",
isSubscription: false,
iapPrice: purchaseEvent.purchasedProduct.metadata.localizedPrice,
iapCurrency: purchaseEvent.purchasedProduct.metadata.isoCurrencyCode);
}
Example
// example
// unity iap servcie process
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
string receiptJson = args.purchasedProduct.receipt;
/*
Processing BACKND receipt verification
*/
BackendReturnObject validation = Backend.Receipt.IsValidateApplePurchase(receiptJson, "receiptDescription");
// When displaying the amount in the console
decimal iapPrice = args.purchasedProduct.metadata.localizedPrice;
string iapCurrency = args.purchasedProduct.metadata.isoCurrencyCode;
BackendReturnObject validation = Backend.Receipt.IsValidateGooglePurchase(receiptJson, "receiptDescription", iapPrice, iapCurrency);
// When receipt verification is successful
if(validation.IsSuccess())
{
// Checks the product ID and provides rewards accordingly
// A consumable product has been purchased by this user.
if(string.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal))
{
Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
// The consumable item has been successfully purchased, add 100 coins to the player's in-game score.
ScoreManager.score += 100;
}
// Or ... a non-consumable product has been purchased by this user.
else if(string.Equals(args.purchasedProduct.definition.id, kProductIDNonConsumable, StringComparison.Ordinal))
{
Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
// TODO: The non-consumable item has been successfully purchased, grant this item to the player.
}
// Or ... a subscription product has been purchased by this user.
else if(string.Equals(args.purchasedProduct.definition.id, kProductIDSubscription, StringComparison.Ordinal))
{
Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
// TODO: The subscription item has been successfully purchased, grant this to the player.
}
}
// When receipt verification fails
else
{
// Or ... an unknown product has been purchased by this user. Fill in additional products here....
Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
}
// Return a flag indicating whether this product has completely been received, or if the application needs
// to be reminded of this purchase at next app launch. Use PurchaseProcessingResult.Pending when still
// saving purchased products to the cloud, and when that save is delayed.
return PurchaseProcessingResult.Complete;
}
ReturnCase
Success cases
When successful\ statusCode : 201\ message : Success\ returnValue : {"usedDate":"2018-10-15T05:17:49Z"}
Error cases
Expired receipt token\ statusCode : 400\ errorCode : BadParameterException\ message : bad token, Invalid token
Tampered/forged receipt token\ statusCode : 400\ errorCode : BadParameterException\ message : bad token, Invalid token
Receipt of refund/cancellation\ statusCode : 402\ errorCode : AbnormalReceipt\ message : This receipt has changed status. purchaseState: cancelled
Already used receipt token\ statusCode : 409\ errorCode : UsedReceipt\ message : This receipt has already been used. usedDate: 2018-02-15T04:01:50.000Z