PageSourceSearch

https://www.electronjs.org/assets/js/80e0db47.ffbab701.js

js electronjs.org collected 2026-09-24 07:04:22 UTC 7,594 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkelectronjs=self.webpackChunkelectronjs||[]).push([["26278"],{57034(e,n,t){t.r(n),t.d(n,{metadata:()=>a,default:()=>l,frontMatter:()=>s,contentTitle:()=>o,toc:()=>p,assets:()=>c});var a=JSON.parse('{"id":"latest/tutorial/in-app-purchases","title":"In-App Purchases","description":"Add in-app purchases to your Mac App Store (MAS) application","source":"@site/docs/latest/tutorial/in-app-purchases.md","sourceDirName":"latest/tutorial","slug":"/latest/tutorial/in-app-purchases","permalink":"/docs/latest/tutorial/in-app-purchases","draft":false,"unlisted":false,"editUrl":"https://github.com/electron/electron/edit/main/docs/tutorial/in-app-purchases.md","tags":[],"version":"current","frontMatter":{"title":"In-App Purchases","description":"Add in-app purchases to your Mac App Store (MAS) application","slug":"in-app-purchases","hide_title":true},"sidebar":"docs","previous":{"title":"Device Access","permalink":"/docs/latest/tutorial/devices"},"next":{"title":"Keyboard Shortcuts","permalink":"/docs/latest/tutorial/keyboard-shortcuts"}}'),r=t(74848),i=t(28453);let s={title:"In-App Purchases",description:"Add in-app purchases to your Mac App Store (MAS) application",slug:"in-app-purchases",hide_title:!0},o="In-App Purchases",c={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Paid Applications Agreement",id:"paid-applications-agreement",level:3},{value:"Create Your In-App Purchases",id:"create-your-in-app-purchases",level:3},{value:"Change the CFBundleIdentifier",id:"change-the-cfbundleidentifier",level:3},{value:"Code example",id:"code-example",level:2}];function d(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"in-app-purchases",children:"In-App Purchases"})}),"\n",(0,r.jsx)(n.h2,{id:"preparing",children:"Preparing"}),"\n",(0,r.jsx)(n.h3,{id:"paid-applications-agreement",children:"Paid Applications Agreement"}),"\n",(0,r.jsx)(n.p,{children:"If you haven't already, you\u2019ll need to sign the Paid Applications Agreement and set up your banking and tax information in iTunes Connect."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://help.apple.com/itunes-connect/developer/#/devb6df5ee51",children:"iTunes Connect Developer Help: Agreements, tax, and banking overview"})}),"\n",(0,r.jsx)(n.h3,{id:"create-your-in-app-purchases",children:"Create Your In-App Purchases"}),"\n",(0,r.jsx)(n.p,{children:"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."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://help.apple.com/itunes-connect/developer/#/devae49fb316",children:"iTunes Connect Developer Help: Create an in-app purchase"})}),"\n",(0,r.jsx)(n.h3,{id:"change-the-cfbundleidentifier",children:"Change the CFBundleIdentifier"}),"\n",(0,r.jsxs)(n.p,{children:["To test In-App Purchase in development with Electron you'll have to change the ",(0,r.jsx)(n.code,{children:"CFBundleIdentifier"})," in ",(0,r.jsx)(n.code,{children:"node_modules/electron/dist/Electron.app/Contents/Info.plist"}),". You have to replace ",(0,r.jsx)(n.code,{children:"com.github.electron"})," by the bundle identifier of the application you created with iTunes Connect."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-xml",children:"<key>CFBundleIdentifier</key>\n<string>com.example.app</string>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"code-example",children:"Code example"}),"\n",(0,r.jsxs)(n.p,{children:["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 ",(0,r.jsx)(n.code,{children:"com.example.app.product1"})," is ",(0,r.jsx)(n.code,{children:"product1"}),"). Note that you have to listen to the ",(0,r.jsx)(n.code,{children:"transactions-updated"})," event as soon as possible in your app."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",children:"// Main process\nconst { inAppPurchase } = require('electron')\n\nconst PRODUCT_IDS = ['id1', 'id2']\n\n// Listen for transactions as soon as possible.\ninAppPurchase.on('transactions-updated', 
1(event, transactions) => {\n  if (!Array.isArray(transactions)) {\n    return\n  }\n\n  // Check each transaction.\n  for (const transaction of transactions) {\n    const payment = transaction.payment\n\n    switch (transaction.transactionState) {\n      case 'purchasing':\n        console.log(`Purchasing ${payment.productIdentifier}...`)\n        break\n\n      case 'purchased': {\n        console.log(`${payment.productIdentifier} purchased.`)\n\n        // Get the receipt url.\n        const receiptURL = inAppPurchase.getReceiptURL()\n\n        console.log(`Receipt URL: ${receiptURL}`)\n\n        // Submit the receipt file to the server and check if it is valid.\n        // @see https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html\n        // ...\n        // If the receipt is valid, the product is purchased\n        // ...\n\n        // Finish the transaction.\n        inAppPurchase.finishTransactionByDate(transaction.transactionDate)\n\n        break\n      }\n\n      case 'failed':\n        console.log(`Failed to purchase ${payment.productIdentifier}.`)\n\n        // Finish the transaction.\n        inAppPurchase.finishTransactionByDate(transaction.transactionDate)\n\n        break\n      case 'restored':\n        console.log(`The purchase of ${payment.productIdentifier} has been restored.`)\n\n        break\n      case 'deferred':\n        console.log(`The purchase of ${payment.productIdentifier} has been deferred.`)\n\n        break\n      default:\n        break\n    }\n  }\n})\n\n// Check if the user is allowed to make in-app purchase.\nif (!inAppPurchase.canMakePayments()) {\n  console.log('The user is not allowed to make in-app purchase.')\n}\n\n// Retrieve and display the product descriptions.\ninAppPurchase.getProducts(PRODUCT_IDS).then((products) => {\n  // Check the parameters.\n  if (!Array.isArray(products) || products.length <= 0) {\n    console.log('Unable to retrieve the product information.')\n    return\n  }\n\n  // Display the name and price of each product.\n  for (const product of products) {\n    console.log(`The price of ${product.localizedTitle} is ${product.formattedPrice}.`)\n  }\n\n  // Ask the user which product they want to purchase.\n  const selectedProduct = products[0]\n  const selectedQuantity = 1\n\n  // Purchase the selected product.\n  inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then((isProductValid) => {\n    if (!isProductValid) {\n      console.log('The product is not valid.')\n      return\n    }\n\n    console.log('The payment has been added to the payment queue.')\n  })\n})\n"})})]})}function l(e={}){let{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453(e,n,t){t.d(n,{R:()=>s,x:()=>o});var a=t(96540);let r={},i=a.createContext(r);function s(e){let n=a.useContext(i);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.