feat: enable explicit IAP restoration (#21461)

This commit is contained in:
Shelley Vohr 2019-12-17 07:07:11 -08:00 committed by GitHub
parent 53957d47d6
commit dba8a0caa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 23 deletions

View file

@ -40,11 +40,17 @@ Retrieves the product descriptions.
### `inAppPurchase.canMakePayments()`
Returns `Boolean`, whether a user can make a payment.
Returns `Boolean` - whether a user can make a payment.
### `inAppPurchase.restoreCompletedTransactions()`
Restores finished transactions. This method can be called either to install purchases on additional devices, or to restore purchases for an application that the user deleted and reinstalled.
[The payment queue](https://developer.apple.com/documentation/storekit/skpaymentqueue?language=objc) delivers a new transaction for each previously completed transaction that can be restored. Each transaction includes a copy of the original transaction.
### `inAppPurchase.getReceiptURL()`
Returns `String`, the path to the receipt.
Returns `String` - the path to the receipt.
### `inAppPurchase.finishAllTransactions()`

View file

@ -85,6 +85,8 @@ void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
prototype->SetClassName(gin::StringToV8(isolate, "InAppPurchase"));
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
.SetMethod("restoreCompletedTransactions",
&in_app_purchase::RestoreCompletedTransactions)
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
.SetMethod("finishAllTransactions",

View file

@ -17,13 +17,15 @@ typedef base::OnceCallback<void(bool isProductValid)> InAppPurchaseCallback;
// --------------------------- Functions ---------------------------
bool CanMakePayments(void);
bool CanMakePayments();
void FinishAllTransactions(void);
void RestoreCompletedTransactions();
void FinishAllTransactions();
void FinishTransactionByDate(const std::string& date);
std::string GetReceiptURL(void);
std::string GetReceiptURL();
void PurchaseProduct(const std::string& productID,
int quantity,

View file

@ -141,6 +141,10 @@ bool CanMakePayments() {
return [SKPaymentQueue canMakePayments];
}
void RestoreCompletedTransactions() {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
void FinishAllTransactions() {
for (SKPaymentTransaction* transaction in SKPaymentQueue.defaultQueue
.transactions) {

View file

@ -51,7 +51,7 @@ class TransactionObserver {
const std::vector<Transaction>& transactions) = 0;
private:
InAppTransactionObserver* obeserver_;
InAppTransactionObserver* observer_;
base::WeakPtrFactory<TransactionObserver> weak_ptr_factory_;

View file

@ -183,14 +183,14 @@ Transaction::Transaction(const Transaction&) = default;
Transaction::~Transaction() = default;
TransactionObserver::TransactionObserver() : weak_ptr_factory_(this) {
obeserver_ = [[InAppTransactionObserver alloc]
observer_ = [[InAppTransactionObserver alloc]
initWithCallback:base::BindRepeating(
&TransactionObserver::OnTransactionsUpdated,
weak_ptr_factory_.GetWeakPtr())];
}
TransactionObserver::~TransactionObserver() {
[obeserver_ release];
[observer_ release];
}
} // namespace in_app_purchase

View file

@ -6,9 +6,14 @@ describe('inAppPurchase module', function () {
this.timeout(3 * 60 * 1000)
it('canMakePayments() does not throw', () => {
it('canMakePayments() returns a boolean', () => {
const canMakePayments = inAppPurchase.canMakePayments()
expect(canMakePayments).to.be.a('boolean')
})
it('restoreCompletedTransactions() does not throw', () => {
expect(() => {
inAppPurchase.canMakePayments()
inAppPurchase.restoreCompletedTransactions()
}).to.not.throw()
})
@ -29,22 +34,23 @@ describe('inAppPurchase module', function () {
})
// The following three tests are disabled because they hit Apple servers, and
// Apple started blocking requests from AWS IPs (we think), so they fail on
// CI.
// Apple started blocking requests from AWS IPs (we think), so they fail on CI.
// TODO: find a way to mock out the server requests so we can test these APIs
// without relying on a remote service.
xit('purchaseProduct() fails when buying invalid product', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist', 1)
expect(success).to.be.false('failed to purchase non-existent product')
})
xdescribe('handles product purchases', () => {
it('purchaseProduct() fails when buying invalid product', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist', 1)
expect(success).to.be.false('failed to purchase non-existent product')
})
xit('purchaseProduct() accepts optional arguments', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist')
expect(success).to.be.false('failed to purchase non-existent product')
})
it('purchaseProduct() accepts optional arguments', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist')
expect(success).to.be.false('failed to purchase non-existent product')
})
xit('getProducts() returns an empty list when getting invalid product', async () => {
const products = await inAppPurchase.getProducts(['non-exist'])
expect(products).to.be.an('array').of.length(0)
it('getProducts() returns an empty list when getting invalid product', async () => {
const products = await inAppPurchase.getProducts(['non-exist'])
expect(products).to.be.an('array').of.length(0)
})
})
})