> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Tutorial: Processing Payments ## Article: Processing Payments ## Article Link: https://dev.wix.com/docs/develop-websites/articles/code-tutorials/wix-pay/tutorial-processing-payments.md ## Article Content: # Velo Tutorial: Processing Payments Using the Velo Pay API you can collect payments from your site's visitors outside the context of a Wix App like Wix Stores. The API allows you to collect a payment when triggered by any user interaction on any page.
**Warning:** Before starting with payments, it is important that you fully understand how to handle the security concerns detailed below that arise when collecting payments.
### Prerequisites Before using the Pay API, you need to set up your site to accept payments. To learn more, see [About Accepting Payments](https://support.wix.com/en/article/about-accepting-payments).
**Note:** When setting up your site to accept payments, be sure to select the payment methods you want to offer and [set your payment currency](https://support.wix.com/en/article/setting-your-currency-for-accepting-payments).
Additionally, you will need to be familiar with creating backend web modules and calling the functions defined in them from page code. To learn more, see [Calling Server-Side Code from the Front-End with Web Modules.](https://dev.wix.com/docs/develop-websites/articles/coding-with-velo/backend-code/web-modules/call-backend-code-from-the-frontend.md) You also might want to familiarize yourself with who can see and call your site's code. To learn more, see the [Code Visibility](https://dev.wix.com/docs/develop-websites/articles/best-practices/security-best-practices.md) section of [Security Considerations When Working with Velo](https://dev.wix.com/docs/develop-websites/articles/best-practices/security-best-practices.md). ### Pay API
**Note:** To work with the Pay API, you need to save and publish your site.
The Pay API is split between backend and client-side functions to facilitate a secure payment process as described [below](https://support.wix.com/en/article/how-to-process-payments-with-code#security-considerations). It consists of two functions and one event: * `createPayment()` - Called in backend code to create a payment and generate a `paymentId`. * `startPayment()` - Called in client-side code to prompt the current site visitor to enter the payment information. * `onPaymentUpdate()` - Fired in backend code when a payment's status has changed. For detailed information on the Pay API see [wix-pay-frontend](https://dev.wix.com/docs/velo/apis/wix-pay-frontend/introduction.md) and [wix-pay-backend](https://dev.wix.com/docs/velo/apis/wix-pay-backend/introduction.md) in the API Reference. ### Payment Lifecycle The following list outlines the steps taken in a typical payment lifecycle: 1. A site visitor clicks a button to start the payment process. 2. The button's event handler calls a backend function. 3. A `PaymentInfo` object containing information about the payment, such as the payment amount, is created in the backend function. 4. The backend function calls `createPayment()` using the `PaymentInfo` object and returns the generated `Payment` object to the calling client-side event handler. 5. The event handler then calls the `startPayment()` function with the `id` from the `Payment` object, which opens the payment popup on your site. 6. The site visitor enters the payment information. 7. The event handler optionally handles the returned `PaymentResult`. 8. Handle additional status updates to the payment transaction using the `onPaymentUpdate()` event. > **Note:** The terms popup and lightbox refer to the same element. While the editor and dashboard now refer to it as a [popup](https://support.wix.com/en/article/studio-editor-using-popups), the API methods continue to use the term lightbox for backward compatibility. The documentation uses both terms accordingly. ### Payment Code Example The following is an example showing the payment lifecycle in code. The numbered comments correspond to the numbered steps in the payment lifecycle described above. ```javascript /******************** * client-side code * ********************/ import { createMyPayment } from 'backend/pay.web'; import wixPayFrontend from 'wix-pay-frontend'; import wixWindowFrontend from 'wix-window-frontend'; // Step 1 - User clicks a button. export function myButton_click(event) { // Step 2 - Call backend function. // (Next, see step 3 in the backend code below.) createMyPayment() // When the payment has been created and a paymentId has been returned: .then( (payment) => { // Step 5 - Call the startPayment() function with the paymentId. // Include PaymentOptions to customize the payment experience. wixPayFrontend.startPayment(payment.id, { "showThankYouPage": false, "termsAndConditionsLink": "https://mysite.com/terms" }) // Step 6 - Visitor enters the payment information. // When the payment form is completed: .then( (result) => { // Step 7 - Handle the payment result. // (Next, see step 8 in the backend code below.) if (result.status === "Successful") { wixWindowFrontend.openLightbox("Success Box"); } else if (result.status === "Pending") { wixWindowFrontend.openLightbox("Pending Box"); } } ); } ); } ``` ```javascript /************************** * backend code - pay.web.js * **************************/ import { Permissions, webMethod } from 'wix-web-module'; import wixPay from 'wix-pay-backend'; export const createMyPayment = webMethod(Permissions.Anyone, () => { // Step 3 - Create payment info object. // Here we use static data. You might want to use data from a // collection. To see an example of such a usage, see the API Reference. let paymentInfo = { "items": [ { name: "Product 1", price: 9.99 }, { name: "Product 2", price: 19.99 } ], amount: 29.98 } // Step 4 - Call createPayment() with the payment information // and return the paymentId. // (Next, see step 5 in the client-side code above.) return wixPay.createPayment(paymentInfo); }); ``` ```javascript /***************************** * backend code - events.js * *****************************/ export function wixPay_onPaymentUpdate(event) { // Step 8 - Handle additional status updates using // the onPaymentUpdate() event. let paymentId = event.payment.id; let newTransactionStatus = event.status; let userInfo = event.userInfo; // Handle new payment status. } ``` ### Security Considerations For security reasons you should always create the `PaymentInfo` object (step 3 above) in backend code. **Do not pass payment information from client-side code.** Passing payment information from client-side code opens a vulnerability which is easily exploited. Since malicious site visitors can call your exported backend functions from the browser, they would be able to alter the payment information that is passed to the backend code. For example, if you pass the price of an item being purchased from client-side code, a user can change the price of the item. To securely process a payment, always define the payment information in the backend. Even though malicious users can call the backend function, they cannot see or change what happens in that function. If needed, you can also include additional validations in your backend function. If you want to perform operations based on a payment's status, always use the status updates received by the backend payment events. Status information that is received in client-side code should only be used for display purposes.