Skip to content

Commit

Permalink
feat: added username to IAP purchaseProduct method (#35902)
Browse files Browse the repository at this point in the history
  • Loading branch information
michalzaq12 committed Dec 12, 2022
1 parent 4e66184 commit 6a798b1
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 11 deletions.
8 changes: 5 additions & 3 deletions docs/api/in-app-purchase.md
Expand Up @@ -21,10 +21,12 @@ Returns:

The `inAppPurchase` module has the following methods:

### `inAppPurchase.purchaseProduct(productID[, quantity])`
### `inAppPurchase.purchaseProduct(productID[, opts])`

* `productID` string - The identifiers of the product to purchase. (The identifier of `com.example.app.product1` is `product1`).
* `quantity` Integer (optional) - The number of items the user wants to purchase.
* `productID` string
* `opts` Integer | Object (optional) - If specified as an integer, defines the quantity.
* `quantity` Integer (optional) - The number of items the user wants to purchase.
* `username` string (optional) - The string that associates the transaction with a user account on your service (applicationUsername).

Returns `Promise<boolean>` - Returns `true` if the product is valid and added to the payment queue.

Expand Down
7 changes: 6 additions & 1 deletion lib/browser/api/in-app-purchase.ts
Expand Up @@ -4,7 +4,12 @@ let _inAppPurchase;

if (process.platform === 'darwin') {
const { inAppPurchase } = process._linkedBinding('electron_browser_in_app_purchase');

const _purchase = inAppPurchase.purchaseProduct as (productID: string, quantity?: number, username?: string) => Promise<boolean>;
inAppPurchase.purchaseProduct = (productID: string, opts?: number | { quantity?: number, username?: string }) => {
const quantity = typeof opts === 'object' ? opts.quantity : opts;
const username = typeof opts === 'object' ? opts.username : undefined;
return _purchase.apply(inAppPurchase, [productID, quantity, username]);
};
_inAppPurchase = inAppPurchase;
} else {
_inAppPurchase = new EventEmitter();
Expand Down
4 changes: 3 additions & 1 deletion shell/browser/api/electron_api_in_app_purchase.cc
Expand Up @@ -178,9 +178,11 @@ v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(

int quantity = 1;
args->GetNext(&quantity);
std::string username = "";
args->GetNext(&username);

in_app_purchase::PurchaseProduct(
product_id, quantity,
product_id, quantity, username,
base::BindOnce(gin_helper::Promise<bool>::ResolvePromise,
std::move(promise)));

Expand Down
1 change: 1 addition & 0 deletions shell/browser/mac/in_app_purchase.h
Expand Up @@ -29,6 +29,7 @@ std::string GetReceiptURL();

void PurchaseProduct(const std::string& productID,
int quantity,
const std::string& username,
InAppPurchaseCallback callback);

} // namespace in_app_purchase
Expand Down
21 changes: 17 additions & 4 deletions shell/browser/mac/in_app_purchase.mm
Expand Up @@ -25,10 +25,12 @@ @interface InAppPurchase : NSObject <SKProductsRequestDelegate> {
@private
in_app_purchase::InAppPurchaseCallback callback_;
NSInteger quantity_;
NSString* username_;
}

- (id)initWithCallback:(in_app_purchase::InAppPurchaseCallback)callback
quantity:(NSInteger)quantity;
quantity:(NSInteger)quantity
username:(NSString*)username;

- (void)purchaseProduct:(NSString*)productID;

Expand All @@ -45,10 +47,12 @@ @implementation InAppPurchase
* to the queue.
*/
- (id)initWithCallback:(in_app_purchase::InAppPurchaseCallback)callback
quantity:(NSInteger)quantity {
quantity:(NSInteger)quantity
username:(NSString*)username {
if ((self = [super init])) {
callback_ = std::move(callback);
quantity_ = quantity;
username_ = [username copy];
}

return self;
Expand Down Expand Up @@ -107,6 +111,7 @@ - (void)checkout:(SKProduct*)product {
// when the transaction is finished).
SKMutablePayment* payment = [SKMutablePayment paymentWithProduct:product];
payment.quantity = quantity_;
payment.applicationUsername = username_;

[[SKPaymentQueue defaultQueue] addPayment:payment];

Expand All @@ -128,6 +133,11 @@ - (void)runCallback:(bool)isProductValid {
[self release];
}

- (void)dealloc {
[username_ release];
[super dealloc];
}

@end

// ============================================================================
Expand Down Expand Up @@ -183,9 +193,12 @@ void FinishTransactionByDate(const std::string& date) {

void PurchaseProduct(const std::string& productID,
int quantity,
const std::string& username,
InAppPurchaseCallback callback) {
auto* iap = [[InAppPurchase alloc] initWithCallback:std::move(callback)
quantity:quantity];
auto* iap = [[InAppPurchase alloc]
initWithCallback:std::move(callback)
quantity:quantity
username:base::SysUTF8ToNSString(username)];

[iap purchaseProduct:base::SysUTF8ToNSString(productID)];
}
Expand Down
9 changes: 7 additions & 2 deletions spec/api-in-app-purchase-spec.ts
Expand Up @@ -39,12 +39,17 @@ describe('inAppPurchase module', function () {
// without relying on a remote service.
xdescribe('handles product purchases', () => {
it('purchaseProduct() fails when buying invalid product', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist');
expect(success).to.be.false('failed to purchase non-existent product');
});

it('purchaseProduct() accepts optional (Integer) argument', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist', 1);
expect(success).to.be.false('failed to purchase non-existent product');
});

it('purchaseProduct() accepts optional arguments', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist');
it('purchaseProduct() accepts optional (Object) argument', async () => {
const success = await inAppPurchase.purchaseProduct('non-exist', { quantity: 1, username: 'username' });
expect(success).to.be.false('failed to purchase non-existent product');
});

Expand Down

0 comments on commit 6a798b1

Please sign in to comment.