In-App Purchases (macOS)

Preparing

Paid Applications Agreement

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.

iTunes Connect Developer Help: Agreements, tax, and banking overview

Create Your In-App Purchases

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

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.

  1. <key>CFBundleIdentifier</key>
  2. <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.

  1. // Main process
  2. const { inAppPurchase } = require('electron')
  3. const PRODUCT_IDS = ['id1', 'id2']
  4. // Listen for transactions as soon as possible.
  5. inAppPurchase.on('transactions-updated', (event, transactions) => {
  6. if (!Array.isArray(transactions)) {
  7. return
  8. }
  9. // Check each transaction.
  10. transactions.forEach((transaction) => {
  11. const payment = transaction.payment
  12. switch (transaction.transactionState) {
  13. case 'purchasing':
  14. console.log(`Purchasing ${payment.productIdentifier}...`)
  15. break
  16. case 'purchased': {
  17. console.log(`${payment.productIdentifier} purchased.`)
  18. // Get the receipt url.
  19. const receiptURL = inAppPurchase.getReceiptURL()
  20. console.log(`Receipt URL: ${receiptURL}`)
  21. // Submit the receipt file to the server and check if it is valid.
  22. // @see https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
  23. // ...
  24. // If the receipt is valid, the product is purchased
  25. // ...
  26. // Finish the transaction.
  27. inAppPurchase.finishTransactionByDate(transaction.transactionDate)
  28. break
  29. }
  30. case 'failed':
  31. console.log(`Failed to purchase ${payment.productIdentifier}.`)
  32. // Finish the transaction.
  33. inAppPurchase.finishTransactionByDate(transaction.transactionDate)
  34. break
  35. case 'restored':
  36. console.log(`The purchase of ${payment.productIdentifier} has been restored.`)
  37. break
  38. case 'deferred':
  39. console.log(`The purchase of ${payment.productIdentifier} has been deferred.`)
  40. break
  41. default:
  42. break
  43. }
  44. })
  45. })
  46. // Check if the user is allowed to make in-app purchase.
  47. if (!inAppPurchase.canMakePayments()) {
  48. console.log('The user is not allowed to make in-app purchase.')
  49. }
  50. // Retrieve and display the product descriptions.
  51. inAppPurchase.getProducts(PRODUCT_IDS).then(products => {
  52. // Check the parameters.
  53. if (!Array.isArray(products) || products.length <= 0) {
  54. console.log('Unable to retrieve the product informations.')
  55. return
  56. }
  57. // Display the name and price of each product.
  58. products.forEach(product => {
  59. console.log(`The price of ${product.localizedTitle} is ${product.formattedPrice}.`)
  60. })
  61. // Ask the user which product he/she wants to purchase.
  62. const selectedProduct = products[0]
  63. const selectedQuantity = 1
  64. // Purchase the selected product.
  65. inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then(isProductValid => {
  66. if (!isProductValid) {
  67. console.log('The product is not valid.')
  68. return
  69. }
  70. console.log('The payment has been added to the payment queue.')
  71. })
  72. })