2022-03-03 17:56:00 +00:00
---
title: In-App Purchases
description: Add in-app purchases to your Mac App Store (MAS) application
slug: in-app-purchases
hide_title: true
---
# In-App Purchases
2018-04-05 06:33:13 +00:00
## Preparing
### Paid Applications Agreement
2020-11-05 22:12:43 +00:00
2019-03-13 20:56:01 +00:00
If you haven't already, you’ ll need to sign the Paid Applications Agreement and set up your banking and tax information in iTunes Connect.
2018-04-05 06:33:13 +00:00
[iTunes Connect Developer Help: Agreements, tax, and banking overview ](https://help.apple.com/itunes-connect/developer/#/devb6df5ee51 )
### Create Your In-App Purchases
2020-11-05 22:12:43 +00:00
2018-04-05 06:33:13 +00:00
Then, you'll need to configure your in-app purchases in iTunes Connect, and include details such as name, pricing, and description that highlights the features and functionality of your in-app purchase.
[iTunes Connect Developer Help: Create an in-app purchase ](https://help.apple.com/itunes-connect/developer/#/devae49fb316 )
### Change the CFBundleIdentifier
To test In-App Purchase in development with Electron you'll have to change the `CFBundleIdentifier` in `node_modules/electron/dist/Electron.app/Contents/Info.plist` . You have to replace `com.github.electron` by the bundle identifier of the application you created with iTunes Connect.
```xml
< key > CFBundleIdentifier< / key >
< string > com.example.app< / string >
```
## Code example
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1` ). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
```javascript
2020-09-14 17:36:54 +00:00
// Main process
const { inAppPurchase } = require('electron')
2018-04-05 06:33:13 +00:00
const PRODUCT_IDS = ['id1', 'id2']
// Listen for transactions as soon as possible.
inAppPurchase.on('transactions-updated', (event, transactions) => {
if (!Array.isArray(transactions)) {
return
}
// Check each transaction.
2023-08-31 14:36:43 +00:00
for (const transaction of transactions) {
2020-07-09 17:18:49 +00:00
const payment = transaction.payment
2018-04-05 06:33:13 +00:00
switch (transaction.transactionState) {
case 'purchasing':
console.log(`Purchasing ${payment.productIdentifier}...`)
break
2020-07-09 17:18:49 +00:00
case 'purchased': {
2018-04-05 06:33:13 +00:00
console.log(`${payment.productIdentifier} purchased.`)
// Get the receipt url.
2020-07-09 17:18:49 +00:00
const receiptURL = inAppPurchase.getReceiptURL()
2018-04-05 06:33:13 +00:00
console.log(`Receipt URL: ${receiptURL}`)
// Submit the receipt file to the server and check if it is valid.
// @see https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
// ...
// If the receipt is valid, the product is purchased
// ...
// Finish the transaction.
inAppPurchase.finishTransactionByDate(transaction.transactionDate)
break
2020-07-09 17:18:49 +00:00
}
2018-04-05 06:33:13 +00:00
case 'failed':
console.log(`Failed to purchase ${payment.productIdentifier}.`)
// Finish the transaction.
inAppPurchase.finishTransactionByDate(transaction.transactionDate)
break
case 'restored':
console.log(`The purchase of ${payment.productIdentifier} has been restored.`)
break
case 'deferred':
console.log(`The purchase of ${payment.productIdentifier} has been deferred.`)
break
default:
break
}
2023-08-31 14:36:43 +00:00
}
2018-04-05 06:33:13 +00:00
})
// Check if the user is allowed to make in-app purchase.
if (!inAppPurchase.canMakePayments()) {
console.log('The user is not allowed to make in-app purchase.')
}
// Retrieve and display the product descriptions.
2019-03-13 20:56:01 +00:00
inAppPurchase.getProducts(PRODUCT_IDS).then(products => {
2018-04-05 06:33:13 +00:00
// Check the parameters.
if (!Array.isArray(products) || products.length < = 0) {
console.log('Unable to retrieve the product informations.')
return
}
// Display the name and price of each product.
2023-08-31 14:36:43 +00:00
for (const product of products) {
2018-04-05 06:33:13 +00:00
console.log(`The price of ${product.localizedTitle} is ${product.formattedPrice}.`)
2023-08-31 14:36:43 +00:00
}
2018-04-05 06:33:13 +00:00
2022-04-06 21:19:32 +00:00
// Ask the user which product they want to purchase.
2020-07-09 17:18:49 +00:00
const selectedProduct = products[0]
const selectedQuantity = 1
2018-04-05 06:33:13 +00:00
// Purchase the selected product.
2019-03-13 20:56:01 +00:00
inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then(isProductValid => {
2018-04-05 06:33:13 +00:00
if (!isProductValid) {
console.log('The product is not valid.')
return
}
console.log('The payment has been added to the payment queue.')
})
})
2019-03-21 19:15:55 +00:00
```