This is the abridged developer documentation for SumUp Developer # Online Payments > Get started with accepting online payments. This guide walks you through creating a sandbox merchant account and processing your first transaction in minutes. import { Steps } from '@astrojs/starlight/components'; import Image from '@components/content/Image.astro'; Online payments form an integral part of the SumUp product portfolio. SumUp supports online payments through multiple approaches to address every merchant use case. Use one of the out-of-the-box integrations or build a complete custom payments flow with the APIs. Your app communicates with SumUp via HTTP requests defined in the [API Reference](/api).​ ![Image showing integrations in SumUp](/img/guides/integrations.png) To get started, review the options SumUp offers for managing online payments. ## Getting a Sandbox Merchant Account To test SumUp APIs and tools without involving real money, use a sandbox merchant account. Create one from your Dashboard account as follows. 1. Log in to your SumUp account. 2. Open [Developer Settings](https://me.sumup.com/settings/developer?tab=sandboxes). 3. In the **Sandboxes** tab, create a sandbox merchant account if you do not have one yet. :::note If you don't have a sandbox account yet, [sign up for a developer account](https://me.sumup.com/signup?signup_intent=developer). This starts you with a sandbox merchant account. ::: A screenshot of the account selection dropdown in the SumUp dashboard with the sandbox merchant account highlighted with red circle With your sandbox merchant account, begin making API calls with real data. Sandbox merchant accounts **do not** process transactions with real funds. The sandbox merchant account has a different ID and displays a clear warning. Requests with a value of 11 (in any currency) always fail by design, to test failed transaction scenarios. A screenshot of the dashboard with sandbox merchant account selected When finished experimenting with the sandbox merchant account, switch back to a regular account for business purposes. ## Authorization All online payment products use SumUp APIs, which require authorization via an API key or access token. See the [Authorization Guide](/tools/authorization/) for details on available options.​ ## Checkout Products SumUp provides a range of checkout products for seamless integration with your website. ### Hosted Checkout Hosted Checkout is the fastest path to launch. SumUp hosts the payment page, while your integration creates the checkout and redirects the customer to the returned URL. See the [Hosted Checkout documentation](/online-payments/checkouts/hosted-checkout/) for details. ### Payment Widget For an embedded checkout on your own site, use the [Payment Widget](/online-payments/checkouts/card-widget/). It only requires adding a single script to your payment page. #### Alternative Payment Methods The Payment Widget supports [Alternative Payment Methods](/online-payments/apm) (APMs) to accept payments beyond traditional card schemes such as Visa and Mastercard. To enable APMs for your Payment Widget integration, use the [contact form](/contact). Available APMs include: - Apple Pay - Bancontact - Blik - Boleto - EPS - Google Pay - iDeal - MyBank - PIX - Przelewy24 - Satispay :::tip The APMs you can offer depend on the location your business is registered and operates in. ::: :::note See the [Payment Methods overview](/online-payments/payment-methods/) for the full list of supported methods grouped by payment method family. ::: ### Swift Checkout SDK The Swift Checkout SDK provides a complete and fast checkout experience to your end users, collecting payment, address, and contact information with a click of a button. See the [Swift Checkout Documentation](/online-payments/checkouts/swift-checkout/) for details. ## Plugins For Prestashop, Wix, or WooCommerce, use SumUp plugins for seamless payments. See the [Plugins section](/online-payments/plugins/) for details on each.​ ## Custom Integrations ### SumUp APIs SumUp provides REST APIs for creating and retrieving checkouts, managing transactions, storing tokenized payment instruments, and issuing refunds. SumUp APIs use API keys or [OAuth 2.0](https://www.rfc-editor.org/rfc/rfc6749) for authentication. Call authenticated API endpoints from your server. Keep API keys and client secrets out of browsers and mobile apps. ### Receiving Payments Start by [choosing a checkout integration](/online-payments/checkouts/). Your server creates a checkout with the amount, currency, merchant code, and a unique checkout reference. The selected checkout integration then collects the customer's payment details and completes the payment without sending raw card details through your server. SumUp supports the following payment paths: - [Hosted Checkout](/online-payments/checkouts/hosted-checkout/) redirects the customer to a SumUp-hosted payment page. - [Payment Widget](/online-payments/checkouts/card-widget/) embeds the SumUp payment form in your website. - [Swift Checkout SDK](/online-payments/checkouts/swift-checkout/) and the [React Native SDK](/online-payments/sdks/react-native/) provide checkout experiences for supported mobile use cases. - [Alternative Payment Methods](/online-payments/apm/) support wallets, bank-based methods, vouchers, and other locally available options. - [Tokenization and recurring payments](/online-payments/guides/tokenization-with-payment-sdk/) use a saved payment instrument rather than raw card details. Do not build a payment form that sends raw card details to the Checkouts API. Use one of the checkout integrations above to collect payment details. ## Contact SumUp :::note Do you have specific questions? Check out our [help page](/help) for the most frequently asked questions or [contact us here](/contact). ::: # 3D Secure authentication > Understand how SumUp handles 3D Secure authentication, exemptions, liability, testing, and failed challenges. 3D Secure (3DS) lets a card issuer authenticate a cardholder during an online card payment. SumUp supports EMV 3DS and starts authentication when it is required for the transaction. Your integration must support the [two primary EMV 3DS flows](https://www.emvco.com/dynamic/emv-3-d-secure-whitepaper-v2/introduction/): - **Frictionless flow:** The issuer completes its assessment without asking the customer to take action. - **Challenge flow:** The issuer asks the customer to verify the payment, for example in their banking app or with a one-time passcode. :::note You cannot determine whether a customer will be challenged. SumUp, the card scheme, and the issuer evaluate the payment and applicable regulatory requirements. Always handle an authentication step when SumUp returns one. ::: ## 3D Secure and Strong Customer Authentication Strong Customer Authentication (SCA) generally requires a customer to authenticate with at least two independent factors: - Something they know, such as a password or PIN - Something they possess, such as a phone or authentication device - Something they are, such as a fingerprint or facial recognition SCA applies to many customer-initiated electronic payments in the European Economic Area and the United Kingdom. An exemption or an out-of-scope transaction can mean that SCA is not applied. An issuer can also require 3DS in markets where SCA is not a regulatory requirement. 3DS is the authentication protocol used for online card payments; SCA is the regulatory requirement. A 3DS flow does not always display a challenge, and the absence of a challenge does not mean that 3DS was skipped. ## Choose an integration path | Integration | 3DS responsibility | | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Hosted Checkout](/online-payments/checkouts/hosted-checkout/) | SumUp presents the payment and authentication flow on the hosted page. Your backend verifies the final checkout status. | | [Payment Widget](/online-payments/checkouts/card-widget/) | The widget presents the authentication flow. Its `onResponse` callback can emit `auth-screen` when a challenge starts. Your backend verifies the final checkout status. | Choose Hosted Checkout for a SumUp-hosted payment page or the Payment Widget for an embedded checkout. ## How the payment flow works 1. Your backend [creates a checkout](/api/checkouts/create) with a unique `checkout_reference` and a `redirect_url`. 2. The customer submits their payment through Hosted Checkout or the Payment Widget. 3. SumUp and the issuer determine whether the payment can proceed without customer interaction or requires a challenge. 4. For a challenge, the customer authenticates directly with their issuer. 5. The customer returns to your `redirect_url` after the external flow finishes. 6. Your backend [retrieves the checkout](/api/checkouts/get) and uses its status as the source of truth. :::caution Reaching the `redirect_url`, receiving a frontend callback, or completing a challenge does not prove that the payment succeeded. Fulfill the order only after your backend retrieves the checkout and confirms that its status is `PAID`. ::: ## Frictionless and challenge flows ### Frictionless flow The issuer uses transaction, device, and account information to assess the payment without asking the customer to take action. Your application might not display an authentication screen. Continue to verify the checkout on your backend. A frictionless customer experience does not change how you confirm the final payment result. ### Challenge flow The issuer asks the customer to complete an authentication step. The challenge interface and available authentication methods are controlled by the issuer and can vary between cards and customers. Your application must allow the customer to: - Leave your checkout for a full-page authentication flow when requested - Return to the `redirect_url` - Retry with another card after failed or unavailable authentication - Safely abandon or resume the order without creating a duplicate charge ## SCA exemptions and out-of-scope payments The [EU regulatory technical standards for SCA](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32018R0389) include exemptions intended to reduce unnecessary customer friction. The issuer always makes the final authentication decision and can request a challenge even when a payment appears to qualify for an exemption. :::note The SumUp Checkouts API does not expose a merchant-selectable SCA exemption parameter. Do not base your integration on a specific exemption being applied. Build it to handle both frictionless and challenge outcomes for every customer-initiated card payment. ::: Common exemption categories include: | Category | What it means for your integration | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Low-value payment | In the EEA, a remote payment of up to €30 can qualify, subject to cumulative amount and consecutive-payment limits. The issuer tracks those limits and can still require authentication. | | Transaction risk analysis | A payment service provider can request an exemption for a qualifying low-risk payment when regulatory fraud-rate and risk-analysis conditions are met. This is not a decision your checkout frontend makes. | | Recurring payment | SCA is normally required when the customer establishes or changes a series of payments for the same amount and recipient. Later payments in that series can qualify for an exemption. | | Trusted beneficiary | A customer can designate a business as trusted through a service offered by their issuer. The issuer controls the list and decides whether to apply the exemption. | Some payments are outside the scope of SCA rather than exempt. For example, a properly established merchant-initiated transaction can be out of scope when it is made without the customer actively participating. It must be linked to the customer's original consent and authenticated setup. See [Tokenization and recurring payments](/online-payments/guides/tokenization-with-payment-sdk/) for the supported SumUp flow. Thresholds and eligibility differ by market and can change. Do not use the categories above as legal advice or implement exemption rules in your frontend. ## Liability and disputes Successful 3DS authentication can shift liability for some fraud-related chargebacks from the merchant to the issuer. The exact outcome depends on the card scheme, market, authentication result, and whether the authentication data was correctly linked to the authorization. 3DS does not guarantee liability protection: - A successful payment status does not by itself confirm a liability shift. - An exemption can leave fraud liability with the merchant or acquirer. - Liability rules for attempted authentication vary by card scheme and region. - 3DS does not prevent disputes unrelated to unauthorized card use, such as goods not received, goods not as described, duplicate processing, or refund disputes. - You must still keep order, delivery, refund, and customer-communication evidence. Treat 3DS as one part of fraud prevention, not as a replacement for risk controls or dispute management. ## Test your integration Use a sandbox merchant account and the test cards below. Use any future expiry date, such as `12/30`, and any three-digit CVV, such as `123`. | Scenario | Test card | Expected behavior | | -------------------------------- | -------------------------- | ------------------------------------------------------------------------------- | | Frictionless success | VISA `4200 0000 0000 0091` | Payment completes without a challenge screen. | | Challenge required | VISA `4200 0000 0000 0042` | The issuer challenge is presented before the payment can complete. | | Authentication technical failure | VISA `4012 0010 3746 1114` | Authentication fails because of a simulated technical error. | | Cardholder not enrolled | VISA `4012 0010 3714 1112` | Authentication cannot complete because the cardholder is not enrolled. | | Issuer not participating | VISA `4532 4970 8877 1651` | Authentication cannot complete because the card or issuer does not participate. | For more card schemes and scenarios, see [Testing online payments](/online-payments/testing/). Verify all of the following before going live: - [ ] A frictionless payment completes without waiting for a challenge event. - [ ] An iframe or browser challenge can be completed and returns the customer to your site. - [ ] Your backend verifies `PAID` before fulfillment. - [ ] A failed or abandoned challenge never produces a paid order in your system. - [ ] Refreshing the return page does not submit or fulfill the order twice. - [ ] A delayed final status is reconciled without creating a second checkout. - [ ] Logs include the checkout ID, checkout reference, timestamps, and final status, but no card data, secrets, or complete authentication payloads. ## Troubleshooting | Symptom | What to check | | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | No challenge screen appears | This can be a valid frictionless outcome. Retrieve the checkout instead of treating the missing challenge as an error. | | `next_step` is returned but the challenge does not open | Use the returned method and URL without modification, submit every payload field, and use a mechanism listed in the response. Check HTTPS, Content Security Policy, popup blocking, and iframe restrictions in the browser console. | | The Payment Widget emits `auth-screen` | This is expected when challenge authentication starts. Wait for the next callback, then verify the checkout from your backend. | | The customer returns but the checkout is still `PENDING` | Do not fulfill or immediately create a replacement checkout. Retry retrieval with bounded backoff and reconcile the result through your backend. | | Authentication fails or the card is not enrolled | Keep the order unpaid, show a recoverable message, and let the customer retry or choose another card. Do not expose issuer or gateway internals in the message. | | The customer abandons the challenge | Keep the order unpaid. Retrieve the existing checkout before deciding whether a new checkout is needed, and use a new unique reference for a genuinely new payment attempt. | | The customer is challenged repeatedly | Confirm that you are not creating multiple checkouts for the same attempt. Challenge decisions remain issuer-controlled and cannot be disabled by the client. | When contacting support, provide the checkout ID, checkout reference, merchant code, approximate timestamp, environment, and final status. Never send card details, API keys, or the complete authentication payload. # Alternative Payment Methods > Learn about supported alternative payment methods, activation steps, and integration options. Alternative Payment Methods (APMs) provide alternatives to standard card payment schemes. They offer familiar and frictionless payment experiences to your customers, while making you stand out from your competitors offering only traditional payment experiences. APMs have completely transformed how we pay online. For example, in the Netherlands more than half of the consumers use iDeal to pay online merchandise. Some types of APMs are prepaid cards, mobile payments, e-wallets, and "buy now, pay later" installment-based schemes. ## Supported Alternative Payment Methods The APMs you can offer depend on the country your business is registered and operating in. Here's a list of the currently available APMs at SumUp: | APM | Country | | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | | Apple Pay | Austria, Belgium, Brazil, Bulgaria, Chile, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Norway, Peru, Poland, Portugal, Romania, Slovenia, Slovakia, Spain, Sweden, Switzerland, United Kingdom | | | Bancontact | Belgium | | | Blik | Poland | | | Boleto | Brazil | | | EPS | Austria | | | Google Pay | Austria, Belgium, Brazil, Bulgaria, Chile, Croatia, Cyprus, Czechia, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Norway, Peru, Poland, Portugal, Romania, Slovenia, Slovakia, Spain, Sweden, Switzerland, United Kingdom | | | iDeal | Netherlands | | | MyBank | Greece, Italy, Spain | | | PIX | Brazil | | | Przelewy24 | Poland | | | Satispay | Italy | | ## Enabling Alternative Payment Methods As a **sole trader**, APMs are automatically enabled for your merchant account after completing the regular registration steps and performing a test transaction with one of our remote payment products, such as [Payment Links](https://sumup.co.uk/payment-links/), [Invoices](https://sumup.co.uk/invoices), and [Online Store](https://sumup.co.uk/online-store/). As with any other legal type, you must request activation from our support team or via our [contact form here](/contact), providing your merchant ID (MXXXXX). Our team will onboard your merchant account and grant access to the APMs applicable to your business location. Once your request is processed, APMs become available within [Payment Links](https://sumup.co.uk/payment-links/), [Invoices](https://sumup.co.uk/invoices), and [Online Store](https://sumup.co.uk/online-store/). :::note At this time APMs are not available in our SumUp plugins. ::: ## Integration You can offer APMs through a number of approaches: - Through the [SumUp Payment Widget](/online-payments/checkouts/card-widget). To make APM payments successful, you must always set a `redirect_url` upon [checkout creation](/api/checkouts/create). Beyond that step, the SumUp Payment Widget will handle the rest. :::note Please note that Google Pay [Terms of Service](https://payments.developers.google.com/terms/sellertos) are applied to all Google Pay transactions via SumUp Payment Widget ::: - [API Integrations](/online-payments/apm/integration-guide/) - Through the [Swift Checkout SDK](/online-payments/checkouts/swift-checkout/) - Direct Integration: - [Apple Pay](/online-payments/apm/apple-pay) - [Google Pay](/online-payments/apm/google-pay) :::caution [Apple Pay](/online-payments/apm/apple-pay) and [Google Pay](/online-payments/apm/google-pay) direct integrations require domain verification in order to be implemented successfully. ::: # Apple Pay > Learn how to integrate Apple Pay, including prerequisites, domain validation, and API calls. import Image from "@components/content/Image.astro"; In this guide, you will learn how to directly integrate Apple Pay with SumUp, so that you can retain your own UI/UX flow. Please note that you can also offer Apple Pay through our Payment Widget (see [Payment Widget documentation](/online-payments/checkouts/card-widget#alternative-payment-methods)). ## Prerequisites - You have a SumUp merchant account and have already filled in your [account details](https://me.sumup.com/account). - Get familiar with [Apple Pay on the Web guide](https://developer.apple.com/documentation/apple_pay_on_the_web). - Offering Apple Pay requires registering with Apple on all web domains that will expose an Apple Pay button (includes TLD and subdomains). This is a requirement for production AND test environments. - If you want to test payments without involving real funds, [create a sandbox merchant account](/online-payments/#getting-a-sandbox-merchant-account). - Complete the domain onboarding setup steps described in your Dashboard under **Settings** > **For developers** > **Payment wallets**. Screenshot of the dashboard Developer Settings, showing Payment wallets section that includes Apple Pay and Google Pay ## Accepting Apple Pay Payments with SumUp To begin your implementation, follow these steps: 1. [Create a checkout](https://developer.sumup.com/api/checkouts/create#create-a-checkout) 2. Create an [Apple Payment request](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaypaymentrequest) ```js const applePaymentRequest = { currencyCode: "EUR", countryCode: "DE", merchantCapabilities: ["supports3DS"], supportedNetworks: ["masterCard", "visa"], total: { label: "Demo", amount: "0.00", type: "final", }, }; ``` 3. Initiate an [Apple Pay session](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/2320659-applepaysession) and call the [begin method](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778001-begin) 4. Listen for the `onvalidatemerchant` callback and collect the validation URL from the event. Create the following payload and pass the validation URL you received from Apple as the `target` value: ```json { "target": "https://apple-pay-gateway-cert.apple.com/paymentservices/startSession", "context": "your_domain_name" } ``` and initiate a merchant session by calling ```http PUT https://api.sumup.com/v0.1/checkouts/${checkoutId}/apple-pay-session ``` 5. Use the response from the previous step to complete merchant validation with the [`completeMerchantValidation`](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778015-completemerchantvalidation/) method. 6. Submitting the payment sheet triggers the `onpaymentauthorized` callback. At that point, [process the checkout](https://developer.sumup.com/api/checkouts/process#process-a-checkout). The process-checkout request body needs to include a `payment_type` of `apple_pay` and an `apple_pay` object containing the Apple Pay payment token returned by the callback. ```json { "payment_type": "apple_pay", "id": "9be2da07-a7bd-4877-bc0a-e16cd909a876", "amount": 12, "currency": "EUR", "apple_pay": { "token": { "paymentData": { "data": "si2xuT2ArQo689SfE-long-token", "signature": "MIAGCSqGSIb3DQEHA-long-signature", "header": { "publicKeyHash": "PWfjDi3TSwgZ20TY/A7f3V6J/1rhHyRDCspbeljM0io=", "ephemeralPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaBtz7UN2MNV0qInJVEEhXy10PU0KfO6KxFjXm93oKWL6lCsxZZGDl/EKioUHVSlKgpsKGin0xvgldfxeJVgy0g==", "transactionId": "62e0568bc9258e9d0e059d745650fc8211d05ef7a7a1589a6411bf9b12cdfd04" }, "version": "EC_v1" }, "paymentMethod": { "displayName": "MasterCard 8837", "network": "MasterCard", "type": "debit" }, "transactionIdentifier": "62E0568BC9258E9D0E059D745650FC8211D05EF7A7A1589A6411BF9B12CDFD04" } } } ``` :::tip Handling the responses from the API calls should be according to our public [API contract and guidelines](/api/). ::: # Google Pay > Learn how to integrate Google Pay, including domain registration, payment requests, and processing. import Image from '@components/content/Image.astro'; In this guide, you will learn how to directly integrate Google Pay with SumUp. Please note that you can also offer Google Pay through our Payment Widget (see [Payment Widget documentation](/online-payments/checkouts/card-widget#alternative-payment-methods)). ## Prerequisites - You have a SumUp merchant account and have already filled in your [account details](https://me.sumup.com/account). - If you want to test payments without involving real funds, [create a sandbox merchant account](/online-payments/#getting-a-sandbox-merchant-account). - Review [Google Pay API terms of service](https://payments.developers.google.com/terms/sellertos). - Complete the domain onboarding setup steps described in your Dashboard under **Settings** > **For developers** > **Payment wallets**. You can read Google's tutorial [Google Pay for Payments](https://developers.google.com/pay/api/web/guides/tutorial), which covers the requirements you're expected to follow in order to successfully offer this payment method. Screenshot of the dashboard Developer Settings, showing Payment wallets section that includes Apple Pay and Google Pay ## Accepting Google Pay Payments with SumUp Considering you've adhered to the prerequisites, the following steps will enable you to begin accepting Google Pay payments through SumUp: 1. Create a base payment request object, containing: - `tokenizationSpecification` object with the following parameters: - `gateway`- always equal to "sumup" - `gatewayMerchantId`- your SumUp merchant code - [`merchantInfo` object](https://developers.google.com/pay/api/web/reference/request-objects#MerchantInfo) with the following keys: - `merchantId`- unique identifier provided to you by Google once you register your domain with them. This is required for `PRODUCTION`. - `merchantName`- your merchant name ```js const baseRequest = { apiVersion: 2, apiVersionMinor: 0, merchantInfo: { merchantId: '123456789123456789', merchantName: 'Example Merchant', }, allowedPaymentMethods: [ { type: 'CARD', parameters: { allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'], allowedCardNetworks: ['MASTERCARD', 'VISA'], }, tokenizationSpecification: { type: 'PAYMENT_GATEWAY', parameters: { gateway: 'sumup', gatewayMerchantId: 'exampleGatewayMerchantId', }, }, }, ], }; ``` 2. Load the [Google Pay API JavaScript library](https://developers.google.com/pay/api/web/guides/tutorial#js-load) on the web page you will offer this payment method 3. Initialize a `PaymentsClient` object for the environment you are implementing. Two values are possible here: `TEST` for testing the integration and `PRODUCTION` for live payments. ```js const paymentsClient = new google.payments.api.PaymentsClient({ environment: 'PRODUCTION', }); ``` 4. [Check readiness to pay](https://developers.google.com/pay/api/web/guides/tutorial#isreadytopay) with Google Pay API 5. [Launch the Google Pay button](https://developers.google.com/pay/api/web/guides/tutorial#add-button) 6. [Create a PaymentDataRequest](https://developers.google.com/pay/api/web/guides/tutorial#paymentdatarequest) using the `baseRequest` object and append the top-level `transactionInfo` and `merchantInfo` objects. Your `PaymentDataRequest` should look like this: ```js const paymentDataRequest = { apiVersion: 2, apiVersionMinor: 0, merchantInfo: { merchantId: '123456789123456789', merchantName: 'Example Merchant', }, transactionInfo: { totalPriceStatus: 'FINAL', totalPriceLabel: 'Total', totalPrice: `${checkoutInfo.amount}`, currencyCode: checkoutInfo.currency || 'EUR', countryCode: 'DE', }, allowedPaymentMethods: [ { type: 'CARD', parameters: { allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'], allowedCardNetworks: ['MASTERCARD', 'VISA'], }, tokenizationSpecification: { type: 'PAYMENT_GATEWAY', parameters: { gateway: 'sumup', gatewayMerchantId: 'exampleGatewayMerchantId', }, }, }, ], }; ``` 7. [Create a checkout](/api/checkouts/create) with SumUp 8. [Call the `loadPaymentData`](https://developers.google.com/pay/api/web/reference/client#loadPaymentData) method and pass it the `PaymentDataRequest` as an argument. This method will respond in a Promise, where if resolved you will receive a `PaymentData` object 9. [Process the checkout](/api/checkouts/process). The process checkout request body needs to include a `payment_type` of `google_pay` and a `google_pay` object, containing the response from the previous step ```json { "payment_type": "google_pay", "id": "6te2da07-a7bd-4877-bc0a-e16cd909a876", "amount": 12, "currency": "EUR", "google_pay": { "apiVersionMinor": 0, "apiVersion": 2, "paymentMethodData": { "description": "Visa •••• 1111", "tokenizationData": { "type": "PAYMENT_GATEWAY", "token": "token-data" }, "type": "CARD", "info": { "cardNetwork": "VISA", "cardDetails": "1111" } } } } ``` :::note Handling the responses from the API calls should be according to our public [API contract and guidelines](/api/). ::: ## Troubleshooting ### Screenshots for Google Google demands screenshots for the onboarding process, but you don't have the integration ready yet? Simply add `#sumup-widget:google-pay-demo-mode` to your URL to render the Google Pay button for onboarding purposes. ### Testing Google Pay Integration Locally This is not possible at the moment. You need to use a staging environment and validate the test domain in Google API console. ### Error Decrypting Google Pay Token An Internal Server Error that points to Google Pay token decryption can be caused by an environment mismatch. Make sure the `PaymentsClient` `environment` matches the Google Pay configuration used to create the payment data: use `TEST` for test flows and `PRODUCTION` for live payments. ```js const paymentsClient = new google.payments.api.PaymentsClient({ environment: 'PRODUCTION', }); ``` # Integration Guide > Learn about the request parameters and flows required to process alternative payment methods. ## Overview Alternative Payment Methods (further referred to as APMs) are similar to normal checkouts. One key difference is that the customer needs to take an additional action in order to finalize the payment with most APMs. Before proceeding, read the [online payments guide](/online-payments/). ## Check Available APMs Check which payment methods are available to your merchant account. 1. [Create a checkout](/api/checkouts/create) and use the checkout `id` to fetch the list of available payment methods from the following endpoint `https://api.sumup.com/v0.1/checkouts/{checkout_id}/payment-methods`. Example response: ```json { "items": [ { "id": "card", "name": "Credit Card" }, { "id": "blik", "name": "Blik" }, { "id": "apple_pay", "name": "Apple Pay" } ] } ``` Note that this object might change between checkouts as APMs are not offered for all currencies and amounts, and we are continuously introducing new APMs for you to offer. We recommend handling the returned payment methods as an allowlist for this checkout, and then picking all the payment methods you want to offer. Do **not** simply display all methods returned if your integration doesn't support them. The customer chooses one of the payment methods from the returned values, sent as part of the process checkout request under `payment_type`. The currently available payment method ids are: `card`, `ideal`, `bancontact`, `boleto`, `eps`, `mybank`, `satispay`, `blik`, `p24`, `pix`, `qr_code_pix`, `apple_pay`, `paypal`, `google_pay`. _name_ is just for display purposes. APMs differ from the behavior of cards. There are two possible flows, which we call `artifacts` or `redirect instructions`, explained in more detail below. APMs also require different input parameters obtained from the customer, as listed below: | Payment method name | Parameters | Flow | | ------------------- | --------------------------------------------------- | -------- | | bancontact | First name, Last name, Country | Redirect | | blik | First name, Last name, Country, Email | Redirect | | boleto | First name, Last name, Country, Email, Address, CPF | Artifact | | eps | First name, Last name, Country, Email | Redirect | | ideal | First name, Last name, Country, Email | Redirect | | myBank | First name, Last name, Country, Email | Redirect | | p24 | First name, Last name, Country, Email | Redirect | | satispay | First name, Last name, Country, Email | Redirect | | pix | | Artifact | | qr_code_pix | | Artifact | Example payload: ```json { "payment_type": "#Payment method name", "personal_details": { "email": "#Email", "first_name:": "#First Name", "last_name": "#Last Name", "tax_id": "#CPF", "address": { "country": "#Country", "city": "#Address", "line1": "#Address", "postal_code": "#Address", "state": "#Address" } } } ``` ### Process Checkout Using Redirect Flow In the Redirect Flow, when the checkout is processed, you receive the `"status": "pending"` parameter and the `next_step` parameter, which means an additional action is required to process the payment.Example response: ```json { ... "status": "pending", "next_step": { "url": "https://apm-redirect-link", "method": "POST", "payload": { "....": "..." } }, ... } ``` Most of the time, this is a simple redirect to a 3rd party page, like Blik, where the customer can pay. But, as shown above, POST requests are also possible. For all calls, ensure that the payload is included, and the appropriate method is used. Once the customer completes the necessary actions on the page, they are redirected to the `redirect_url` specified under the [create checkout request](/api/checkouts/create). Now you can retrieve the final status via a [GET checkout request](/api/checkouts/get/). ### Process Checkout Using Payment Method Artifacts Flow Payment method artifacts are images, PDFs etc. which the customer gets in order to pay. Currently, we have 3 payment methods which have artifacts: `boleto`, `pix` and `qr_code_pix`. Example requests for each: **boleto:** ```json { "boleto": { "barcode": "23790001246004987209031123456704579990000010000", "url": "https://api.sumup.com/v0.1/checkouts/19c11c6c-be1d-4dd6-b718-2798878117cb/boletos/1044833949", "valid_until": "2022-02-01T17:57:10.442+00:00", "artefacts": [ { "name": "invoice", "content_type": "application/pdf", "location": "https://homolog.meiosdepagamentobradesco.com.br/apiboleto/Bradesco?token=bWJvYXpkc1hXRzdhRVkyUUFGZUV4T25NYjBVVEZrNG93Y3RKLzM4cTh5dWdDWEh5dDQyTXN6ZHl5NFdjaHBkZg..", "created_at": "2022-01-21T17:57:10.443+00:00" }, { "name": "code", "content_type": "text/plain", "location": "https://api.sumup.com/v0.1/artefacts/5266b29e-625b-43c0-a74a-8985ea3acd8a/content", "content": "23790001246004987209031123456704579990000010000", "created_at": "2022-01-21T17:57:10.445+00:00" } ] } } ``` **pix:** ```json { "pix": { "artefacts": [ { "name": "barcode", "content_type": "image/jpeg", "location": "https://api.sumup.com/v0.1/artefacts/ee69508f-1b16-4ead-8416-8d2085933e6f/content", "created_at": "2021-10-12T22:06:46.327+00:00" }, { "name": "code", "content_type": "text/plain", "location": "https://api.sumup.com/v0.1/artefacts/1e1e5130-17d1-495a-8e36-2a50d40dacde/content", "content": "00020126580014br.gov.bcb.pix0136a4fac492-d03b-45a8-bd43-c3f23d4bac68520400005303986540520.005802BR5916Priscila Manhaes6009Sao Paulo62290525SUMUP202110122206453822986304A61E", "created_at": "2021-10-12T22:06:46.326+00:00" } ] } } ``` **qr_code_pix:** ```json { "qr_code_pix": { "artefacts": [ { "name": "barcode", "content_type": "image/jpeg", "location": "https://api.sam-app.ro/v0.1/artefacts/ee69508f-1b16-4ead-8416-8d2085933e6f/content", "created_at": "2021-10-12T22:06:46.327+00:00" }, { "name": "code", "content_type": "text/plain", "location": "https://localhost:3000/v0.1/artefacts/1e1e5130-17d1-495a-8e36-2a50d40dacde/content", "content": "00020126580014br.gov.bcb.pix0136a4fac492-d03b-45a8-bd43-c3f23d4bac68520400005303986540520.005802BR5916Priscila Manhaes6009Sao Paulo62290525SUMUP202110122206453822986304A61E", "created_at": "2021-10-12T22:06:46.326+00:00" } ] } } ``` The major difference between `qr_code_pix` and `pix` is that `pix` is paid directly into the merchant's SumUp bank account if they have one. `qr_code_pix` is paid out with the normal payout process and incurs a fee. For all artifact payments, you need to provide the customer with the artifact and wait for the checkout to eventually complete. Once the user has paid, you can retrieve the final status via the [GET checkout request](/api/checkouts/get/). # Checkout Integrations > Compare SumUp checkout integrations for embedded, hosted, and accelerated online payment experiences. SumUp provides the following checkout integrations for online payments: - [Payment Widget](/online-payments/checkouts/card-widget/) - embedded checkout UI for cards and supported payment methods - [Hosted Checkout](/online-payments/checkouts/hosted-checkout/) - SumUp-hosted payment page with minimal integration effort - [Swift Checkout SDK](/online-payments/checkouts/swift-checkout/) - accelerated wallet checkout for Apple Pay and Google Pay - [Server-side SDKs](/tools/sdks/) - JavaScript, Go, Python, Java, PHP, .NET, and Rust clients for the SumUp API - [SumUp CLI](/tools/cli/) - command-line access to the SumUp API for development and automation - [React Native SDK](/online-payments/sdks/react-native/) - payment sheet for mobile apps # Payment Widget > Explore the SumUp Payment Widget, including mounting and configuration for your site. import { Steps } from "@astrojs/starlight/components"; import CardWidget from "@components/content/CardWidget.astro"; The Payment Widget, available to all SumUp merchants, is an embedded checkout for card and supported alternative payment methods. It collects payment details and sends them directly to SumUp, supports 3D Secure authentication for card payments, and provides flexible customization options. For card payments, it dynamically recognizes the brand and shows the relevant brand icon. A secure HTTPS connection is used to submit the payment information. For production usage we only support HTTPS for the payment page. (note: [during development browsers will treat `localhost` as secure](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Secure_Contexts#potentially_trustworthy_origins)). ## Prerequisites Payment Widget requires only the ability to create online checkouts via [SumUp checkout API](/api/checkouts/create), authorized by API key or access token (see the [Authorization Guide](/tools/authorization/) for details).​ ## Compliance ### Payment Card Industry When integrated as documented, the Payment Widget collects and sends card details directly to SumUp, so they do not pass through your server. This reduces the PCI DSS scope of your integration, but it does not make your business automatically compliant. You are still responsible for [validating your PCI DSS compliance](https://www.pcisecuritystandards.org/faqs/does-pci-dss-apply-to-merchants-who-outsource-all-payment-processing-operations-and-never-store-process-or-transmit-cardholder-data/) and confirming the requirements that apply to your environment with your acquirer or a Qualified Security Assessor. ### Payment Services Directive 2 Strong Customer Authentication (SCA) may apply to European online payments. The Payment Widget supports 3D Secure and presents any authentication challenge requested by the card issuer. The issuer decides whether authentication is frictionless, challenged, or exempt. See the [3D Secure guide](/online-payments/3ds/) for integration behavior and testing scenarios. ## Integration 1. To integrate the Payment Widget on your website, include the `sdk.js` script on your payment page. ```html ``` 2. Once the script is loaded, you have access to a global variable `SumUpCard`, with a `mount` method which renders the available payment methods. 3. [Create a checkout](/api/checkouts/create) and copy the returned `id`. 4. Pass the returned `id` from the checkout response to the widget component. ```html
``` The Payment Widget makes a request to execute the checkout and after the request is completed, you get a response based on the callback function configured. As a result of successful integration, you can see the following component:
## Configurations The Payment Widget allows you to customize certain properties on the payment form, as listed below. To override the default settings, add your own configuration property-value pairs to the `SumUpCard.mount` method. ```js SumUpCard.mount({ checkoutId: "...", // 'config-name': 'config-value' }); ``` | Property Name | Description | Value | Default Value | Required | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------- | | `checkoutId` | The unique ID you receive once you [create a checkout](/api/checkouts/create). | `string` | _no default value_ | yes | | `onResponse` | The callback function that will be called when you receive a response from the payment form. The first parameter is one of the following: | `function` | `null` | no | | `onLoad` | The callback function that will be called when the Payment Widget is loaded. | `function` | `null` | no | | `onPaymentMethodsLoad` | The callback is called when the payment methods are loaded for the given `checkoutId`. Usually used for when the host page needs to change depending on the payment methods available.

Payment methods can be filtered in order to limit those shown by the widget. `return` the list of payment methods for the widget to render as an _Array of Strings_. E.g. to show only Boleto, when available: `() => ['boleto']`; | `function` | `null` | no | | `onChangeInstallments`\* | The callback function that will be called when the user changes the dropdown for installments. The first and only parameter will be the number of selected installments. (`showInstallments` must be enabled). | `function` | `null` | no | | `showSubmitButton` | Displays or hides the form's submit button. | `boolean` | `true` | no | | `showFooter` | Displays or hides "Powered by SumUp" label. | `boolean` | `true` | no | | `showInstallments`\* | Displays or hides a dropdown for choosing installments. Once enabled this overrides any value of the configuration `installments` and will not display `amount` on the submit button. | `boolean` | `false` | no | | `showZipCode`\*\* | Displays or hides ZIP code input field. It is mandatory for merchant users from USA. | `boolean` | `false` | no | | `showEmail` | Displays or hides email input field. At some time in the future it'll be a mandatory field for every integrator because of the SCA. | `boolean` | `false` | no | | `email` | Alternative way (to `showEmail`) to pass user's email if for example you know it from a previous step in your application. This configuration doesn't display additional input fields. If for some reason both `showEmail` and `email` are passed the `email` will have no effect over the displayed input field. | `string` | `null` | no | | `installments`\* | The number of installments with which the transaction should be processed. | `number`
[1 .. 12] | `null` | no | | `maxInstallments`\* | The maximum amount of installments in the selector displayed by the widget. | `number`
[1 .. 12] | `12` | no | | `id` | `id` of the element that you wish to render the Payment Widget in. _Example:_ `
` | `string` | `"sumup-card"` | no | | `donateSubmitButton` | Changes the text of the submit button to "Donate". | `boolean` | `false` | no | | `amount` | The `amount` you want to be displayed on the submit button. _Requires_ `currency` _and_ `locale` _to take effect._ | `string` | `null` | no | | `currency` | The `currency` for the `amount` you want to be displayed on the submit button. | One of: `"EUR"`, `"BGN"`, `"BRL"`, `"CHF"`, `"CZK"`, `"DKK"`, `"GBP"`, `"HUF"`, `"NOK"`, `"PLN"`, `"SEK"`, `"USD"` | `null` | no | | `locale` | Translates all texts into the given locale. Also specifies the formatting of the `amount` and `currency`. | One of:
`"bg-BG"`, `"cs-CZ"`, `"da-DK"`, `"de-AT"`, `"de-CH"`, `"de-DE"`, `"de-LU"`, `"el-CY"`, `"el-GR"`, `"en-GB"`, `"en-IE"`, `"en-MT"`, `"en-US"`, `"es-CL"`, `"es-ES"`, `"et-EE"`, `"fi-FI"`, `"fr-BE"`, `"fr-CH"`, `"fr-FR"`, `"fr-LU"`, `"hu-HU"`, `"it-CH"`, `"it-IT"`, `"lt-LT"`, `"lv-LV"`, `"nb-NO"`, `"nl-BE"`, `"nl-NL"`, `"pt-BR"`, `"pt-PT"`, `"pl-PL"`, `"sk-SK"`, `"sl-SI"`, `"sv-SE"` | `"en-GB"` | no | | `country` | Sets the country where the user account is from. | One of: `"AT"`, `"BE"`, `"BG"`, `"BR"`, `"CH"`, `"CL"`, `"CO"`, `"CY"`, `"CZ"`, `"DE"`, `"DK"`, `"EE"`, `"ES"`, `"FI"`, `"FR"`, `"GB"`, `"GR"`, `"HR"`, `"HU"`, `"IE"`, `"IT"`, `"LT"`, `"LU"`, `"LV"`, `"MT"`, `"NL"`, `"NO"`, `"PE"`, `"PL"`, `"PT"`, `"RO"`, `"SE"`, `"SI"`, `"SK"`, `"US"` | `null` | no | | `googlePay` | Required for accepting payments with the widget via Google Pay:
For more details check [Google Pay **`merchantInfo`** documentation](https://developers.google.com/pay/api/web/reference/request-objects#MerchantInfo). | `{merchantId: string, merchantName: string}` | `null` | no | _\* Installments are available only to merchant users in Brazil, Chile, Colombia and Peru._
_\*\* ZIP code is required only for merchant users in the USA._ ## Methods | Name | Description | Parameters | Return Type | | ------- | ----------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `mount` | Initializes and renders the payment form. | JSON object with a [configuration](#configurations). | Returns object that contains three methods: `submit`, `unmount` and `update`. | ## Alternative Payment Methods Depending on the country a merchant is registered in, [Alternative Payment Methods (APMs)](/online-payments/apm) are available for accepting payments from your customers. Please note, the `show*` configuration properties from the [widget configurations](#configurations) do not apply to APMs. The APMs will only render fields applicable to the respective payment method. You can begin offering APMs to your customers, once you are onboarded as a merchant. Request assistance with getting onboarded for APMs through our [contact form](/contact). :::note Installments are not applicable to Alternative Payment Methods. ::: ## Custom Styling Custom styling to most of the SumUp Payment Widget elements is enabled by the `data-sumup-id` attribute. To get all elements, query the DOM with `document.querySelectorAll('[data-sumup-id]')`. Here's an example of updating styles for one of the elements: ```css [data-sumup-id="widget__container"] { color: red; line-height: 18px; } ``` You can also style child elements to those with the `data-sumup-id`, by chaining their tag or other uniquely identifiable attribute. Elements like Payment Selector have some additional items you can query to extend your customizations. To style a specific Payment Selector, you need to appoint the `data-sumup-item=${payment.id}`. ```css [data-sumup-id="payment_option"][data-sumup-item="blik"] { display: none; } ``` ## Using Your Own Submit Button If you need to use your own submit button, you can achieve this by following the example below: ```html ``` ## Handling Strict Content Security Policies Pages with strict [Content Security Policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP) may experience issues with styles or images when rendering the SumUp Payment Widget. This section contains the necessary adjustments to render the Payment Widget properly. To confirm your issue is related to CSP, check your browser's console for a similar error message: ```text Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' \*\*\* Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution. ``` ### Required Configurations To render the Payment Widget with CSP in place, you must allow the following URLs in your application: | Content Type | URL | | ------------ | ----------------------------------- | | SDK & API | 'https://\*.sumup.com' | | Images | 'data:', 'https://static.sumup.com' | Additionally, `nonce` is required to make inline styles work on your host page. For more information view [the CSP docs](https://content-security-policy.com/nonce/). Example implementation with `nonce`: ```js const express = require("express"); const app = express(); const http = require("http"); const server = http.createServer(app); const port = process.env.PORT || 4000; const crypto = require("crypto"); // Resources const apisToConnect = ["https://gateway.sumup.com", "https://api.sumup.com"]; const imagesResources = [ "data:", // inline icons "https://static.sumup.com", // For generated barcodes "https://api.sumup.com", ]; const scriptsResources = [ "https://gateway.sumup.com", // PLUS nonce-$HASH ]; const stylesResources = [ // nonce-$HASH ]; const framesResources = ["https://gateway.sumup.com"]; app.get("/", (req, res) => { const nonce = crypto.randomBytes(16).toString("base64"); res.setHeader( "Content-Security-Policy", `default-src 'self';` + ` connect-src 'self' ${apisToConnect.join(" ")};` + ` img-src 'self' ${imagesResources.join(" ")};` + ` script-src 'self' ${scriptsResources.join(" ")} 'nonce-${nonce}';` + ` style-src 'self' 'nonce-${nonce}';` + ` frame-src 'self' ${framesResources.join(" ")};`, ); // res.send(`

Test CSP

Test using generated nonce: ${nonce}
See without nonce
Footer
`); }); server.listen(port, () => { console.log("listening on:", port); }); ``` If you continue to experience issues with rendering the Payment Widget, reach out to our support through this [contact form](/contact). ### Apple Pay specific policies To allow Apple Pay functionality on third party browsers, make sure to allow Apple Pay SDK domain in your CSP: ```text default-src 'self' applepay.cdn-apple.com ...; script-src 'self' applepay.cdn-apple.com ... ``` This is an optional feature, not including these policies will simply prevent Apple Pay from extended availability on unsupported browsers. :::caution Note that Apple Pay is available on all SDKs, but only Swift Checkout SDK extends this feature to third party browsers. ::: # Hosted Checkout > Use Hosted Checkout to accept online payments with a SumUp-hosted payment page and minimal integration effort. import { Tabs, TabItem } from "@astrojs/starlight/components"; import Image from "@components/content/Image.astro"; Hosted Checkout lets you accept online payments with a payment page hosted by SumUp. Your integration creates a checkout through the SumUp API, receives a `hosted_checkout_url`, and sends the customer to that page to complete the payment. This is the lowest-effort way to launch an online checkout while keeping payment collection, status pages, and wallet support inside a SumUp-hosted flow. A screenshot of the Hosted Checkout form showing available payment options, including Google Pay, Apple Pay, and card payment ## Prerequisites - Ability to [create a checkout](/api/checkouts/create) through the SumUp API. - Authentication via API key or access token. See the [Authorization Guide](/tools/authorization/). - A server-side integration to create the checkout and keep credentials secret. ## How Hosted Checkout Works 1. Create a checkout and set `hosted_checkout.enabled` to `true`. 2. Store the returned checkout `id` and `hosted_checkout_url`. 3. Redirect the customer to `hosted_checkout_url`, or share that URL in the flow you are building. 4. After the customer completes the payment, verify the final result through the API or with [webhooks](/online-payments/webhooks/). :::note A Hosted Checkout session is available for 30 minutes. After that, unpaid sessions show an expired or not found page. ::: ## Create a Hosted Checkout Send a request to the [Create a checkout endpoint](/api/checkouts/create) with `hosted_checkout.enabled` set to `true`. If you want the success page to link back to your website, include `redirect_url` at the same time. ```bash curl -X POST https://api.sumup.com/v0.1/checkouts \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SUMUP_API_KEY" \ -d '{ "amount": 12.00, "checkout_reference": "b50pr914-6k0e-3091-a592-890010285b3d", "currency": "EUR", "description": "A sample checkout", "merchant_code": "MCXXXXXX", "redirect_url": "https://example.com/orders/123/complete", "hosted_checkout": { "enabled": true } }' ``` ```ts const checkout = await client.checkouts.create({ merchant_code: merchantCode, amount: 12.0, currency: "EUR", checkout_reference: "b50pr914-6k0e-3091-a592-890010285b3d", description: "A sample checkout", redirect_url: "https://example.com/orders/123/complete", hosted_checkout: { enabled: true }, }); ``` ```csharp var checkout = await client.Checkouts.CreateAsync(new CheckoutCreateRequest { MerchantCode = merchantCode, Amount = 12.0f, Currency = Currency.Eur, CheckoutReference = "b50pr914-6k0e-3091-a592-890010285b3d", Description = "A sample checkout", RedirectUrl = "https://example.com/orders/123/complete", HostedCheckout = new CheckoutCreateRequestHostedCheckout { Enabled = true, }, }); ``` ```java var checkout = client.checkouts().createCheckout( CheckoutCreateRequest.builder() .merchantCode(merchantCode) .amount(12.0f) .currency(Currency.EUR) .checkoutReference("b50pr914-6k0e-3091-a592-890010285b3d") .description("A sample checkout") .redirectUrl("https://example.com/orders/123/complete") .hostedCheckout( CheckoutCreateRequestHostedCheckout.builder() .enabled(true) .build() ) .build() ); ``` ```go checkout, err := client.Checkouts.Create(ctx, sumup.CheckoutsCreateParams{ MerchantCode: merchantCode, Amount: 12.0, Currency: sumup.CurrencyEUR, CheckoutReference: "b50pr914-6k0e-3091-a592-890010285b3d", Description: "A sample checkout", RedirectURL: "https://example.com/orders/123/complete", HostedCheckout: &sumup.CheckoutHostedCheckout{ Enabled: true, }, }) ``` ```py checkout = client.checkouts.create( CreateCheckoutBody( merchant_code=merchant_code, amount=12.00, currency="EUR", checkout_reference="b50pr914-6k0e-3091-a592-890010285b3d", description="A sample checkout", redirect_url="https://example.com/orders/123/complete", hosted_checkout={"enabled": True}, ) ) ``` ```rust let checkout = client.checkouts().create(Some(CheckoutCreateRequest { merchant_code, amount: 12., currency: Currency::EUR, checkout_reference: "b50pr914-6k0e-3091-a592-890010285b3d".into(), description: Some("A sample checkout".into()), redirect_url: Some("https://example.com/orders/123/complete".into()), hosted_checkout: Some(CheckoutCreateRequestHostedCheckout { enabled: true, }), return_url: None, customer_id: None, purpose: None, id: None, status: None, date: None, valid_until: None, transactions: None, })).await?; ``` ```php $checkout = $sumup->checkouts->create([ 'merchant_code' => $merchantCode, 'amount' => 12.00, 'currency' => 'EUR', 'checkout_reference' => 'b50pr914-6k0e-3091-a592-890010285b3d', 'description' => 'A sample checkout', 'redirect_url' => 'https://example.com/orders/123/complete', 'hosted_checkout' => [ 'enabled' => true, ], ]); ``` The response includes the hosted checkout configuration and the URL you send the customer to: ```json { "amount": 12, "checkout_reference": "b50pr914-6k0e-3091-a592-890010285b3d", "checkout_type": "checkout", "currency": "EUR", "date": "2000-01-01T12:49:24.899+00:00", "description": "A sample checkout", "hosted_checkout": { "enabled": true }, "hosted_checkout_url": "https://checkout.sumup.com/pay/8f9316a3-cda9-42a9-9771-54d534315676", "id": "64553e20-3f0e-49e4-8af3-fd0eca86ce91", "merchant_code": "MCXXXXXX", "merchant_country": "DE", "merchant_name": "Sample Shop", "purpose": "CHECKOUT", "status": "PENDING", "transactions": [] } ``` ## Redirect Customers to the Hosted Page Use the `hosted_checkout_url` returned by the API as the payment page URL in your application. - Redirect the customer there immediately after checkout creation. - Or store the URL and present it later in your own flow, for example in an order confirmation page or email. When the customer opens the Hosted Checkout page, SumUp handles the payment UI and payment confirmation flow. The business branding shown on Hosted Checkout, such as your business logo and icon, can be configured from the [Branding page](https://me.sumup.com/settings/branding) in SumUp Dashboard. The business name and other customer-facing information can be configured from the [Business profile page](https://me.sumup.com/settings/business-profile/information). ## Configure the Return Flow If you want the success page to include a button back to your website, set `redirect_url` when you create the checkout, as shown in the examples above. If `redirect_url` is present, the success page shows a button that sends the customer back to your website. ## Handle Payment Outcomes Hosted Checkout covers the customer-facing flow from payment page to final status page. Depending on the outcome, customers see different pages: - Success page after a successful payment. - Failure page when payment authorization or processing fails. - Expired page when the checkout session is no longer valid. - Not found page when the URL does not match an active hosted checkout session. :::tip Treat the hosted page as the customer interface, but use the checkout status and webhook events as the source of truth for your backend order state. ::: ### Success A screenshot of the Hosted Checkout payment success page ### Failure A screenshot of the Hosted Checkout payment failure page ### Expired Session A screenshot of the Hosted Checkout session expired page ### Not Found A screenshot of the Hosted Checkout page not found state # Swift Checkout SDK > Learn about the Swift Checkout SDK to offer Apple Pay and Google Pay on your website with minimal setup. The Swift Checkout SDK enables you to offer a complete and fast checkout experience to your end users, allowing you to collect payment, address, and contact information with a click of a button. Swift Checkout SDK allows for Google Pay and Apple Pay setup. ## Prerequisites - Add a payment method to your browser or wallet. For example, you can save a card in Chrome, add a card to your Apple Wallet for Safari and iOS - Serve your application over HTTPS. This is a requirement both in development and in production environments. One way to get up and running is to use a service like [ngrok](https://ngrok.com/) Currently available payment methods through Swift Checkout SDK: :::caution For pages that have a strict Content Security Policy (CSP) visit the [Handling CSP](/online-payments/checkouts/card-widget/#handling-strict-content-security-policies) instructions. ::: - [Apple Pay](#apple-pay-setup) - [Google Pay](#google-pay-setup) ## SumUp Swift Checkout SDK Setup Include the SDK.js in your page as shown below: ```html
``` Or with JavaScript: ```javascript function injectScript() { return new Promise((resolve) => { var script = document.createElement("script"); script.type = "text/javascript"; script.onload = function () { resolve(window.SumUp); }; script.src = "https://js.sumup.com/swift-checkout/v1/sdk.js"; document.body.appendChild(script); }); } ``` Once the script is loaded, a new SumUp object is injected into the window instance representing SumUp SDK namespace, which contains the SwiftCheckout client. ## Obtaining a Public API Key To obtain a public API key, go to the [API keys page](https://me.sumup.com/settings/api-keys) in the SumUp Dashboard. Your public merchant key will be automatically generated with a `Private` label and a value such as `sup_pk_0x98lsJhJAs...u5kvg`. ## SumUp Swift Checkout Client ```javascript const swiftCheckoutClient = new window.SumUp.SwiftCheckout( "sup_pk_0x98lsJhJAs...u5kvg", ); ``` The client contains a set of objects to render a payment element UI, request payment authorization and process a payment using SumUp’s API. ### Payment Request Object The payment request object requests payment authorizations made with various payment methods. It requires an argument that contains a set of details, information about the requested transaction to be processed, that will be presented to the user to authorize the payment later. Payment request object arguments consist of: - `countryCode`: Represents the country or region of the merchant’s principle place of business. - `total`: Represents what is about to be paid by the user, E.g. a summary of an order. It requires a `label` and an `amount`. The `amount` value must be provided as a string in major unit and should use a period (`.`) as a decimal separator. More specifically, the `amount` value should match the following regex: `^[0-9]+(\.[0-9][0-9])?$` Optional: - `locale`: Represents the locale the text "Pay with \{\{payment method\}\}" will be displayed with in the buttons. ```js const paymentRequest = swiftCheckoutClient.paymentRequest({ countryCode: "DE", locale: "de-DE", total: { label: "My goods", amount: { currency: "EUR", value: "65.00" }, }, }); ``` - `shippingOptions`: Represents a collection of shipping methods the end user can select from to receive their purchased goods. The initial `shippingOptions` list can be later modified according to the shipping address the user selects in the payment dialog. ```js const paymentRequest = swiftCheckoutClient.paymentRequest({ shippingOptions: [ { id: "post", label: "postal service", amount: { currency: "EUR", value: "0.00" }, description: "free post", }, ], }); ``` This object is an analogue to the [PaymentRequest - Web APIs](https://developer.mozilla.org/en-US/docs/Web/API/PaymentRequest/PaymentRequest). The payment request instance contains the logic related to **checking payment method availability and showing** the payment method dialogue once the user interacts with a **payment element**. ### Payment Request Interface All methods in the payment request object are asynchronous. Listed below are the payment request methods and their usage: #### `canMakePayment` Checks if the given merchant public key has access to at least one payment method and checks the payment method availability in the given environment (browser). Returns a promise that resolves in a `boolean`. #### `availablePaymentMethods` Returns the available payment methods for a merchant. Returns a promise that resolves in an `array` of objects representing each available payment method. #### `show` Shows the payment authorization dialogue for a given payment method. It requires an object containing a `paymentMethod`, which defines the selected payment method. This method is usually used along with the `PaymentElement`'s `onSubmit` event. The `show` method resolves with a `AuthorizedPayment`, which contains the `details` shared by the user once they authorize the payment request. The property `details` contains `paymentMethod`, `contactInformation`, `shippingAddress` and may contain `shippingOptions`. A `PaymentRequestCancelledError` will be thrown when the user rejects or cancels the transaction. ```js paymentRequest .show({ paymentMethod: "apple_pay" }) .then(processCheckoutAttempt) .then(handleResponse) .catch((error) => { if ( error instanceof SumUp.SwiftCheckout.Errors.PaymentRequestCancelledError ) { console.log("Cancelled by the user"); } else { throw error; } }); ``` #### `abort` Terminates a payment request before it is processed. Once a payment request has been terminated using this method, the payment request will not be processed and the payment dialogue will be closed. ```js if (someCustomCheck()) { try { await paymentRequest.abort(); // will throw an error. console.log("Payment request aborted due to my custom reason."); } catch (e) { console.error( "Unable to abort, because the user is currently in the process of paying.", ); } } ``` :::note The `abort` method should only be used if the payment request has not yet been processed. Attempting to cancel a payment request after it has been processed may result in unexpected behavior. ::: #### `onShippingAddressChange` Allows adding an event handler which will be triggered every time the user changes their shipping address. The handler can optionally provide a return value to change the following in the payment dialog: - `total` - `shippingOptions` ```js paymentRequest.onShippingAddressChange(async (newShippingAddress) => { const { total, shippingOptions } = await someAsyncOperation(newShippingAddress); return { total, shippingOptions, }; }); ``` :::note To protect user privacy, browsers might hide non-essential and sensitive details from the shipping address, and only provide data required for shipping cost estimation. The extent of information provided can vary based on the chosen browser and payment method, leading to certain fields being absent. For example, the displayed shipping address might be limited to the city, state, country, and ZIP code. The full shipping address is disclosed only in the `PaymentResponse` object after the payment is authorized by the account holder. ::: #### `onShippingOptionsChange` Allows adding an event handler which will be triggered every time the user changes their shipping option choice. The handler can optionally provide a return value to change the following in the payment dialog: - `total` - `shippingAddress` - `shippingOptions` ```js paymentRequest.onShippingOptionsChange(async (selectedShippingOption) => { const { newTotal, newShippingAddress, newShippingOptions } = await someAsyncOperation( total shippingOption, ); return { total, shippingAddress, shippingOptions, }; }); ``` ### Payment Element Builder In order to request a payment, you need to create a UI element. The SDK provides a built-in PaymentElement UI builder, which allows you to create and configure the payment buttons. _Each payment button can be rendered individually as well._ The Swift Elements Builder allows you to attach an `onSubmit` handler, which will be called once the user clicks on one of the buttons rendered by it. You can pass a `label` option to `elements()` to control the wallet button text, and the `mount` method accepts a `paymentMethods` array to filter the payment methods you want to offer. The arguments passed during `mount`, will render one or more buttons: ```js const buttons = swiftCheckoutClient.elements({ label: "book", }); buttons .onSubmit((paymentEvent) => console.log(paymentEvent)) .mount({ paymentMethods: [ { id: "apple_pay" }, { id: "google_pay" }, // See `paymentRequest.availablePaymentMethods()` for all available payment methods ], container: document.querySelector("#express-checkout-container"), }); ``` #### `label` Sets the action text used by the rendered Apple Pay and Google Pay buttons. The supported values are `book`, `buy`, `checkout`, `donate`, `order`, `pay`, `plain`, and `subscribe`. Use the following labels depending on the checkout context: - `book` for reservations, appointments, and other booking flows - `buy` for standard ecommerce purchases - `checkout` when you want the wallet button to match a broader checkout step - `donate` for donation and contribution flows - `order` for order-placement flows such as food ordering or fulfillment - `pay` for paying an existing amount due, such as an invoice or bill - `plain` for a minimal wallet-branded button without extra action text - `subscribe` for subscription and recurring purchase flows Label rendering depends on wallet and browser support. For example, `label: "book"` can be used to show booking-oriented Apple Pay and Google Pay buttons where supported. On Google Pay, `buy`, `pay`, and `plain` can also show the card brand and last four digits when the user's payment method is an eligible card. :::caution Apple Pay has additional requirements for donation flows. Before using `label: "donate"` with Apple Pay, make sure your organization is approved to accept donations with Apple Pay and use the donation-specific Apple Pay setup described in Apple’s [Apple Pay for Donations](https://developer.apple.com/apple-pay/nonprofits/) guide. ::: #### Rendering Buttons for Available Payment Methods Once the UI and Payment Request are configured, you have to check the availability of Swift payment methods and `mount` them into the page. The SDK checks several factors to determine if a given payment method is available: - Is the payment method available for the given merchant? - Is the payment method available on the browser? - Is the wallet/card ready to accept payment requests? After checking if making payments is possible, render the payment element into a given placeholder as shown below: ```js paymentRequest.canMakePayment().then((isAvailable) => { if (isAvailable) { paymentRequest.availablePaymentMethods().then((paymentMethods) => { buttons.mount({ paymentMethods, container: document.querySelector("#express-checkout-container"), }); }); } else { console.error("No payment method available!"); } }); ``` ### Requesting Payment Authorization The authorization dialogue is where the user will review the payment requested, select a payment card and a shipping address. Finally, they can authorize the payment request to be **processed**. Using the payment element builder, configure it to `show` the payment authorization dialogue from the Payment Request instance upon the `onSubmit` event. Once the user authorizes the payment the `show` method will resolve a `PaymentResponse` containing details about the payment authorization. ```js buttons.onSubmit((paymentMethodEvent) => { paymentRequest .show(paymentMethodEvent) .then((paymentResponse) => console.log(paymentResponse)); }); ``` To understand more about the PaymentResponse objects see Mozilla's official [PaymentResponse - Web APIs](https://developer.mozilla.org/en-US/docs/Web/API/PaymentResponse) documentation. ### Processing an Authorized Payment Request To process a payment, the SumUp API requires you to create a checkout for a given amount. The checkout creation requires an authenticated request. Thus, we recommend implementing an endpoint on your backend that will authenticate with our API, create a checkout and return a `checkoutId`. Once you obtain a `checkoutId`, call the `processCheckout` method from the SwiftCheckout client with the `checkoutId` and the `PaymentResponse`, which was received in the previous step, to start the processing the checkout. ```js paymentRequest .show(paymentMethodEvent) .then((paymentResponse) => { console.log(paymentResponse.details); // contactInfo, shippingAddress, etc. // here you create your order and a sumup checkout const checkoutId = "c463bf5e-d397-4bca-9d2e-a4e04f668b1c"; return swiftCheckoutClient.processCheckout(checkoutId, paymentResponse); }) .then(console.log) .catch(console.error); ``` ### The Complete Implementation ```js const swiftCheckoutClient = new window.SumUp.SwiftCheckout( "fOcmczrYtYMJ7Li5GjMLLcUeC9dN", ); const paymentRequest = swiftCheckoutClient.paymentRequest({ total: { label: "One Shoe", amount: { value: "100.0", }, }, shippingOptions: [ { id: "post", label: "postal service", amount: { currency: "EUR", value: "0.00" }, description: "free post", }, ], }); const buttons = swiftCheckoutClient.elements({ label: "book", }); buttons.onSubmit((paymentMethodEvent) => { paymentRequest .show(paymentMethodEvent) .then((paymentResponse) => { console.log(paymentResponse.details); // Create your order and a checkout const checkoutId = "c463bf5e-d397-4bca-9d2e-a4e04f668b1c"; return swiftCheckoutClient.processCheckout(checkoutId, paymentResponse); }) .then((result) => { if (result.status === "PAID") { window.location.href = "/thankyou"; } else { console.error( "It was not possible to process the checkout", result.message, ); } }) .catch((error) => { if ( error instanceof SumUp.SwiftCheckout.Errors.PaymentRequestCancelledError ) { console.error("Cancelled by the user"); } else { throw error; } }); }); paymentRequest.canMakePayment().then((isAvailable) => { if (isAvailable) { paymentRequest.availablePaymentMethods().then((paymentMethods) => { buttons.mount({ paymentMethods, container: document.querySelector("#express-checkout-container"), }); }); } else { console.error("No payment method is available."); } }); ``` ## Error Handling The Swift Checkout SDK returns a series of Errors depending on the event that has taken place. You can use the errors to customise the user experience and communicate error causes as you see fit. - `PaymentRequestCancelledError` is thrown when the end user closes the open payment dialog or presses the button `esc`. - `PaymentRequestInvalidActionError` is thrown when the end user has submitted the payment dialog and then attempted to cancel the payment. Once the payment form is submitted the payment can no longer be cancelled. - `PaymentRequestInternalError` is thrown when attempting to handle the payment request in a forbidden manner. Reasons that you may receive include the following codes, available in the `code` field of the Error object: - `SHIPPING_CONTACT_SELECTION` - `SHIPPING_ADDRESS_SELECTION` - `SHIPPING_METHOD_SELECTION` - `INTERNAL_VALIDATION` - `COMPLETE_PAYMENT` - `UNKNOWN` ## Apple Pay Setup ### Prerequisites - [Verify your domain with Apple Pay](#verify-your-domain-with-apple-pay), both in development and production - For Apple Pay [additional configurations](#apple-pay-setup) are required, including macOS 10.12.1+ or iOS 10.1+ ### Verify Your Domain with Apple Pay To use Apple Pay, verify every domain and subdomain where you display an Apple Pay button, both in development and production. 1. Open [Apple Pay settings in your SumUp profile](https://me.sumup.com/settings/apple-pay). 2. Click **Add Domain**. 3. Click **Download domain verification file** to download the domain association file. 4. Host the file at `https://[DOMAIN_NAME]/.well-known/apple-developer-merchantid-domain-association`, replacing `[DOMAIN_NAME]` with your domain or subdomain. :::note You don't need to create an Apple Merchant ID or Certificate Signing Request (CSR) to use Apple Pay with the Swift Checkout SDK. Use the verification file downloaded from your SumUp profile. Make sure it is publicly accessible at the URL above without adding a file extension. ::: ## Google Pay Setup ### Prerequisites - [Request production access](https://pay.google.com/business/console/) to Google Pay for your domain name - Adhere to the [Google Pay requirements](https://developers.google.com/pay/api/web/guides/setup#get-started) - Review [Google Pay API terms of service](https://payments.developers.google.com/terms/sellertos) ### Google Pay Specific Parameters Google Pay’s base payment request object requires a few unique parameters: - [`merchantInfo` object](https://developers.google.com/pay/api/web/reference/request-objects#MerchantInfo) with the following keys: - `merchantId`- unique identifier provided to you by Google once you [register your domain](https://pay.google.com/business/console/) with them - `merchantName`- your merchant name Here’s an example of how the merchantInfo object is included in a Google Pay payment request: ```js const paymentRequest = sumUpClient.paymentRequest({ methodData: [ { supportedMethods: "google_pay", data: { merchantInfo: { merchantId: "123456789123456789", merchantName: "Example Merchant", }, }, }, ], }); ``` ### Validating Your Domain with Google Pay In order to use Google Pay you need to validate your domain with Google. This process requires rendering a nonfunctional Google Pay button on your website and providing them with screenshots of your checkout flow. To render a Google Pay button on your shop in demo mode, you need to add the `#sumup:google-pay-demo-mode` hash to the page's URL. Once the hash has been applied you can proceed with the domain validation steps: 1. Create an account in the [Google Pay console](https://pay.google.com/business/console) 2. Go to the **Google Pay API** tabitem in your Google Pay console 3. Navigate to the **Integrate with your website** and click on **+ Add website** 4. Fill out the form with the requested information (domain name, buyflow screenshots, etc.) 5. At the top of the page click on **Submit for approval** # Custom Integrations > Integration guides for building with SumUp SDKs and APIs. import { Steps } from '@astrojs/starlight/components'; import Image from '@components/content/Image.astro'; Guides in this section cover the basics of SumUp APIs, allowing you to develop a custom integration if SumUp products don't fully support your use case. ## Getting a Sandbox Merchant Account Create a sandbox merchant account to test APIs without real money: 1. Log in to your SumUp account. 2. Open [Developer Settings](https://me.sumup.com/settings/developer?tab=sandboxes). 3. In the **Sandboxes** tab, create a sandbox merchant account if you do not have one yet. :::note If you don't have a sandbox account yet, [sign up for a developer account](https://me.sumup.com/signup?signup_intent=developer). This starts you with a sandbox merchant account. ::: A screenshot of the account selection dropdown in the SumUp dashboard with the sandbox merchant account highlighted with red circle With your sandbox merchant account, begin making API calls with real data. Sandbox merchant accounts **do not** process transactions with real funds. The sandbox merchant account has a different ID and displays a clear warning. Requests with a value of 11 (in any currency) always fail by design, to test failed transaction scenarios. A screenshot of the dashboard with sandbox merchant account selected When finished experimenting with the sandbox merchant account, switch back to a regular account for business purposes. SumUp provides official SDKs for JavaScript, Go, Python, Java, PHP, .NET, and Rust, as well as the [SumUp CLI](/tools/cli/) for working from a terminal. Visit the [SDKs overview page](/tools/sdks/) to choose the client that fits your stack. # Refunds > Walks through looking up transactions and issuing full or partial refunds. import { Tabs, TabItem } from '@astrojs/starlight/components'; import Multicode from '@components/content/Multicode.astro'; ## Overview In this guide, you will learn how to refund a transaction. You will go through the following steps: 1. [Look up a transaction ID (Optional)](#1-look-up-a-transaction-id) 2. [Refund a transaction](#2-refund-a-transaction) by using one of the available options: - [Option A: Make a full refund](#make-a-full-refund) - [Option B: Make a partial refund](#make-a-partial-refund) When you complete these steps, the payment you have previously processed through SumUp will be refunded either partially or in full. ## Before You Begin Here are the things that you need in order to complete the steps in this guide: - [SumUp merchant account](https://me.sumup.com/login) with completed [account details](https://me.sumup.com/account). - You can also use a [sandbox merchant account](/online-payments/#getting-a-sandbox-merchant-account). - [Registered client application](/tools/authorization/oauth/#register-an-oauth-application) with SumUp. - Valid access token obtained with the [Authorization code flow](/tools/authorization/oauth/#authorization-code-flow). - You have processed a checkout and you have the checkout ID. :::note Transactions are associated with active merchant user accounts. As a result, you _cannot_ use an access token obtained via the [Client credentials flow](/tools/authorization/oauth/#client-credentials-flow) to complete the steps in this guide. ::: ## Steps ### 1. Look up a Transaction ID :::note If you already have the ID of the transaction you want to refund, you can skip this step and continue with [Step 2](#2-refund-a-transaction). ::: 1. Make a GET request to the `https://api.sumup.com/v0.1/checkouts/{id}` endpoint, where the value of the `{id}` path parameter is the identifier of the checkout resource. Example request: ```bash curl -X GET \ https://api.sumup.com/v0.1/checkouts/4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2 \ -H "Authorization: Bearer $SUMUP_API_KEY" ``` ```ts const checkout = await client.checkouts.get("4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2"); ``` ```csharp var checkout = await client.Checkouts.GetAsync("4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2"); ``` ```java var checkout = client.checkouts().getCheckout("4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2"); ``` ```go ctx := context.Background() client := sumup.NewClient() checkout, err := client.Checkouts.Get(ctx, "4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2") ``` ```py checkout = client.checkouts.get("4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2") ``` ```rust let checkout = client .checkouts() .get("4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2") .await?; ``` ```php $checkout = $sumup->checkouts->get('4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2'); $checkoutReference = $checkout->checkout_reference; $checkoutId = $checkout->id; ``` The response contains a JSON body with the full details of the processed checkout resource. You can find the transaction ID in the `id` attribute of the respective transaction resource (`664200af-2b62-4142-9c73-a2a505310d78` in the sample response below). ```json { "checkout_reference": "CO287866", ... "id": "4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2", ... "transactions": [ { "id": "664200af-2b62-4142-9c73-a2a505310d78", ... } ] } ``` ### 2. Refund a Transaction - [Option A: Make a full refund](#make-a-full-refund) - [Option B: Make a partial refund](#make-a-partial-refund) #### Make a Full Refund 1. Make a POST request with an empty request body to the `https://api.sumup.com/v0.1/me/refund/{txn_id}` endpoint, where the value of the `{txn_id}` path parameter is the identifier of the transaction resource. Example request for the transaction with identifier `664200af-2b62-4142-9c73-a2a505310d78`: ```bash curl -X POST \ https://api.sumup.com/v0.1/me/refund/19aa3cca-89f6-42d2-b462-463b0b53e959 \ -H "Authorization: Bearer $SUMUP_API_KEY" ``` ```ts await client.transactions.refund("19aa3cca-89f6-42d2-b462-463b0b53e959"); ``` ```csharp await client.Transactions.RefundAsync("19aa3cca-89f6-42d2-b462-463b0b53e959"); ``` ```java client.transactions().refundTransaction( "19aa3cca-89f6-42d2-b462-463b0b53e959", RefundTransactionRequest.builder().build() ); ``` ```go ctx := context.Background() client := sumup.NewClient() err := client.Transactions.Refund(ctx, "19aa3cca-89f6-42d2-b462-463b0b53e959", sumup.TransactionsRefundParams{}) ``` ```py from sumup.transactions.resource import RefundTransactionBody client.transactions.refund( "19aa3cca-89f6-42d2-b462-463b0b53e959", RefundTransactionBody(), ) ``` ```rust client .transactions() .refund("19aa3cca-89f6-42d2-b462-463b0b53e959", None) .await?; ``` ```php $sumup->transactions->refund('19aa3cca-89f6-42d2-b462-463b0b53e959'); ``` The response returns a 204 HTTP status code and contains no body. #### Make a Partial Refund 1. Make a POST request to the `https://api.sumup.com/v0.1/me/refund/{txn_id}` endpoint, where the value of the `{txn_id}` path parameter is the identifier of the transaction resource. Unlike the option for a full refund, the request body for partial refunds should be a JSON object with the amount you want to refund for the transaction. Example request for a partial refund for the amount of 24.42 EUR: ```bash curl -X POST \ https://api.sumup.com/v0.1/me/refund/19aa3cca-89f6-42d2-b462-463b0b53e959 \ -H "Authorization: Bearer $SUMUP_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"amount": 24.42}' ``` ```ts await client.transactions.refund("19aa3cca-89f6-42d2-b462-463b0b53e959", { amount: 24.42, }); ``` ```csharp await client.Transactions.RefundAsync( "19aa3cca-89f6-42d2-b462-463b0b53e959", new TransactionsRefundRequest { Amount = 24.42f, }); ``` ```java client.transactions().refundTransaction( "19aa3cca-89f6-42d2-b462-463b0b53e959", RefundTransactionRequest.builder().amount(24.42f).build() ); ``` ```go ctx := context.Background() client := sumup.NewClient() amount := float32(24.42) client.Transactions.Refund(ctx, "19aa3cca-89f6-42d2-b462-463b0b53e959", sumup.TransactionsRefundParams{ Amount: &amount, }) ``` ```py from sumup.transactions.resource import RefundTransactionBody client.transactions.refund( "19aa3cca-89f6-42d2-b462-463b0b53e959", RefundTransactionBody(amount=24.42), ) ``` ```rust use sumup::resources::transactions::RefundTransactionBody; client .transactions() .refund( "19aa3cca-89f6-42d2-b462-463b0b53e959", Some(RefundTransactionBody { amount: Some(24.42) }), ) .await?; ``` ```php $sumup->transactions->refund('19aa3cca-89f6-42d2-b462-463b0b53e959', [ 'amount' => 24.42, ]); ``` The response returns a 204 HTTP status code and contains no body. ## Result You have successfully refunded a transaction (either partially or in full) for a payment you previously processed. The refunded amount will be credited to the same payment method the customer had used to pay with in the original transaction. The processing fees associated with the original transaction are not returned. # Response Handling > Explains how to interpret SumUp API responses. ## Overview Once an API call is submitted to SumUp, you will receive a standard HTTP response informing you if your request has been successful or not. In most cases the HTTP codes are accompanied by a response body in [JSON](https://json.org/) format. Codes in the `2xx` range indicate success,`4xx` range indicates errors where the information provided results in a failure. Codes in the `5xx` range are rare and indicate server-side errors. ## Successful Requests Successfully processed requests return one of the following HTTP status codes: `200 OK`, `201 Created`, `202 Accepted`, `204 No Content`. Depending on the use case response bodies may not be present at all. A response body can look like this: ```json { "next_step": { "url": "https://dummy-3ds-gateway.com/cap?RID=1233&VAA=A", "method": "POST", "redirect_url": "https://mysite.com/completed_purchase", "mechanism": "iframe", "payload": { "PaReq": "eJxVUttu2zAM/RXDr4MjyY5dO6BVuE27FZuDZHGG9VGRmMSFb/..f16+jLt/gPhUvGGw==", "MD": "b1a536c0-29b9-11eb-adc1-0242ac120002" } } } ``` ## Client-Side Issues `4xx` are occasions where you can take action to correct your application requests. Typically, these codes are returned upon user error, such as invalid API calls, incorrect values, missing parameters, etc. The response you receive will provide an indication to the root cause that triggered it. Here's an example of a `4xx` response: ```json { "message": "Validation error", "error_code": "MISSING", "param": "merchant_code" } ``` ## Server-Side Issues `5xx` stand for server errors. Although rare, if you receive such code, we recommend retrying your request. Should the returned codes continue to be in the `5xx` range, [reach out to us](/contact). # Save Customer Cards > Tokenize cards with the Payment Widget for future recurring payments. import { Tabs, TabItem } from '@astrojs/starlight/components'; import Image from '@components/content/Image.astro'; ## About Card Tokenization In this guide, you will learn how to use the Payment Widget to save a customer's card as a tokenized payment instrument and set up recurring payments. The Payment Widget handles the payment interface, consent collection, and 3D Secure authentication. This feature is also known as **card on file** or **tokenization**. You will go through the following steps: 1. [Create a customer](#creating-customer). 2. [Create a checkout for card tokenization](#creating-checkout-to-save-card). This is where 3D Secure authentication takes place. The transaction amount is instantly reimbursed. 3. [Process the payment with the Payment Widget](#processing-request-with-payment-widget). 4. [Retrieve the tokenized card](#retrieving-tokenized-card). 5. [Make subsequent payments with the tokenized card](#processing-recurring-payments). ## Prerequisites - You have a merchant account with [SumUp](https://me.sumup.com/login) and have already filled in your [account details](https://me.sumup.com/account). - You can also create a [sandbox merchant account](/online-payments/#getting-a-sandbox-merchant-account). Please note that setting up 3DS verification in a sandbox merchant account requires contacting our team through the [contact form](/contact). - You have an API Key. For more details see the [Authorization Guide](/tools/authorization/api-keys/). - You have control over the backend server to retrieve data securely. ## Creating Customer A customer resource is a representation of a person or business paying for a product or service. It contains personal information such as name, contact details, postal address, as well as a unique identifier relevant to your business logic (`customer_id`). 1. Create a new customer resource with a POST request to the `https://api.sumup.com/v0.1/customers` endpoint: ```bash curl -X POST \ https://api.sumup.com/v0.1/customers \ -H "Authorization: Bearer $SUMUP_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "MYCUSTOMERID-123", "personal_details": { "address": { "city": "Venice", "state": "California", "country": "US", "line1": "606 Venezia Ave", "line2": "Front", "postal_code": "90291" }, "birthdate": "1949-11-11", "email": "thedude@example.com", "first_name": "Jeffrey", "last_name": "Lebowski", "phone": "+1 310-555-1234" } }' ``` ```ts const customer = await client.customers.create({ customer_id: "MYCUSTOMERID-123", personal_details: { first_name: "Jeffrey", last_name: "Lebowski", email: "thedude@example.com", phone: "+1 310-555-1234", birth_date: "1949-11-11", address: { city: "Venice", state: "California", country: "US", line_1: "606 Venezia Ave", line_2: "Front", postal_code: "90291", }, }, }); ``` ```csharp var customer = await client.Customers.CreateAsync(new Customer { CustomerId = "MYCUSTOMERID-123", PersonalDetails = new PersonalDetails { FirstName = "Jeffrey", LastName = "Lebowski", Email = "thedude@example.com", Phone = "+1 310-555-1234", BirthDate = new System.DateTime(1949, 11, 11), Address = new AddressLegacy { City = "Venice", State = "California", Country = "US", Line1 = "606 Venezia Ave", Line2 = "Front", PostalCode = "90291", }, }, }); ``` ```java var customer = client.customers().createCustomer( Customer.builder() .customerId("MYCUSTOMERID-123") .personalDetails( PersonalDetails.builder() .firstName("Jeffrey") .lastName("Lebowski") .email("thedude@example.com") .phone("+1 310-555-1234") .birthDate(java.time.LocalDate.parse("1949-11-11")) .address( AddressLegacy.builder() .city("Venice") .state("California") .country("US") .line1("606 Venezia Ave") .line2("Front") .postalCode("90291") .build() ) .build() ) .build() ); ``` ```go str := func(v string) *string { return &v } customer, err := client.Customers.Create(ctx, sumup.CustomersCreateParams{ CustomerID: "MYCUSTOMERID-123", PersonalDetails: &sumup.PersonalDetails{ FirstName: str("Jeffrey"), LastName: str("Lebowski"), Email: str("thedude@example.com"), Phone: str("+1 310-555-1234"), Address: &sumup.AddressLegacy{ City: str("Venice"), State: str("California"), Country: str("US"), Line1: str("606 Venezia Ave"), Line2: str("Front"), PostalCode: str("90291"), }, }, }) ``` ```py from sumup.customers.resource import CreateCustomerBody from sumup.customers.types import AddressLegacy, PersonalDetails customer = client.customers.create( CreateCustomerBody( customer_id="MYCUSTOMERID-123", personal_details=PersonalDetails( first_name="Jeffrey", last_name="Lebowski", email="thedude@example.com", phone="+1 310-555-1234", birth_date="1949-11-11", address=AddressLegacy( city="Venice", state="California", country="US", line_1="606 Venezia Ave", line_2="Front", postal_code="90291", ), ), ) ) ``` ```rust let customer = client .customers() .create(sumup::resources::customers::Customer { customer_id: "MYCUSTOMERID-123".into(), personal_details: Some(sumup::resources::common::PersonalDetails { first_name: Some("Jeffrey".into()), last_name: Some("Lebowski".into()), email: Some("thedude@example.com".into()), phone: Some("+1 310-555-1234".into()), birth_date: None, tax_id: None, address: Some(sumup::resources::common::AddressLegacy { city: Some("Venice".into()), state: Some("California".into()), country: Some("US".into()), line_1: Some("606 Venezia Ave".into()), line_2: Some("Front".into()), postal_code: Some("90291".into()), }), }), }) .await?; ``` ```php $customer = $sumup->customers->create([ 'customer_id' => 'MYCUSTOMERID-123', 'personal_details' => [ 'first_name' => 'Jeffrey', 'last_name' => 'Lebowski', 'email' => 'thedude@example.com', 'phone' => '+1 310-555-1234', 'address' => [ 'city' => 'Venice', 'state' => 'California', 'country' => 'US', 'line_1' => '606 Venezia Ave', 'line_2' => 'Front', 'postal_code' => '90291', ], ], ]); ``` You should expect a standard `201 Created` response, with the customer details you passed. For full details, see the [endpoint documentation](/api/customers/create). Having created the customer, we can now proceed to making a payment ## Creating Checkout to Save Card Now, we need to tokenize the customer's card, and we will need a checkout for this. The checkout resource is a representation of a payment being made by the previously created customer. It contains information such as the amount, currency, and a unique `checkout_reference` identifier that is relevant to your business logic. The flow is initiated with the `create a checkout` endpoint. It is important to pass the `customer_id` parameter in this step, for future linking to a payment instrument. Critically, a `purpose` parameter is passed to indicate the payment type as **recurring payment** and process an authorization charge of the checkout amount indicated, **which is instantly reimbursed**. Note that this doesn't automatically imply further payments from this customer - at this point, we're just tokenizing the card. 1. To create a new checkout resource, make a POST request to the `https://api.sumup.com/v0.1/checkouts` endpoint. Example of such request: ```bash curl -X POST \ https://api.sumup.com/v0.1/checkouts \ -H "Authorization: Bearer $SUMUP_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "checkout_reference": "MYCHECKOUT", "amount": 1, "currency": "EUR", "merchant_code": "MDEERENR", "description": "My checkout", "customer_id": "MYCUSTOMERID-123", "purpose": "SETUP_RECURRING_PAYMENT" }' ``` ```ts const checkout = await client.checkouts.create({ checkout_reference: "MYCHECKOUT", amount: 1, currency: "EUR", merchant_code: "MDEERENR", description: "My checkout", customer_id: "MYCUSTOMERID-123", purpose: "SETUP_RECURRING_PAYMENT", }); ``` ```csharp var checkout = await client.Checkouts.CreateAsync(new CheckoutCreateRequest { CheckoutReference = "MYCHECKOUT", Amount = 1.0f, Currency = Currency.Eur, MerchantCode = "MDEERENR", Description = "My checkout", CustomerId = "MYCUSTOMERID-123", Purpose = "SETUP_RECURRING_PAYMENT", }); ``` ```java var checkout = client.checkouts().createCheckout( CheckoutCreateRequest.builder() .checkoutReference("MYCHECKOUT") .amount(1.0f) .currency(Currency.EUR) .merchantCode("MDEERENR") .description("My checkout") .customerId("MYCUSTOMERID-123") .purpose(CheckoutCreateRequestPurpose.SETUP_RECURRING_PAYMENT) .build() ); ``` ```go customerID := "MYCUSTOMERID-123" purpose := sumup.CheckoutCreateRequestPurposeSetupRecurringPayment description := "My checkout" checkout, err := client.Checkouts.Create(ctx, sumup.CheckoutsCreateParams{ CheckoutReference: "MYCHECKOUT", Amount: 1, Currency: sumup.CurrencyEUR, MerchantCode: "MDEERENR", Description: &description, CustomerID: &customerID, Purpose: &purpose, }) ``` ```py from sumup.checkouts.resource import CreateCheckoutBody checkout = client.checkouts.create( CreateCheckoutBody( checkout_reference="MYCHECKOUT", amount=1, currency="EUR", merchant_code="MDEERENR", description="My checkout", customer_id="MYCUSTOMERID-123", purpose="SETUP_RECURRING_PAYMENT", ) ) ``` ```rust let checkout = client .checkouts() .create(Some(sumup::resources::checkouts::CheckoutCreateRequest { checkout_reference: "MYCHECKOUT".into(), amount: 1.0, currency: sumup::resources::checkouts::Currency::EUR, merchant_code: "MDEERENR".into(), description: Some("My checkout".into()), customer_id: Some("MYCUSTOMERID-123".into()), purpose: Some("SETUP_RECURRING_PAYMENT".into()), id: None, status: None, date: None, valid_until: None, transactions: None, return_url: None, redirect_url: None, })) .await?; ``` ```php $checkout = $sumup->checkouts->create([ 'checkout_reference' => 'MYCHECKOUT', 'amount' => 1, 'currency' => 'EUR', 'merchant_code' => 'MDEERENR', 'description' => 'My checkout', 'customer_id' => 'MYCUSTOMERID-123', 'purpose' => 'SETUP_RECURRING_PAYMENT', ]); ``` You should expect a standard `201 Created` response, with the checkout reference and both merchant and customer information. ```json { "amount": 1, "checkout_reference": "MYCHECKOUT", "checkout_type": "checkout", "currency": "EUR", "customer_id": "MYCUSTOMERID-123", "date": "2025-10-29T15:09:11.550+00:00", "description": "My checkout", "id": "7164c99b-13cb-42a1-8ba1-3c2c46a29de7", "merchant_code": "MDEERENR", "merchant_country": "PL", "merchant_name": "Sandbox Merchant Account", "pay_to_email": "a8e019f9bb2f49159182e8bd61eb5ea6@developer.sumup.com", "purpose": "SETUP_RECURRING_PAYMENT", "status": "PENDING", "transactions": [] } ``` For more information, see the [create a checkout](/api/checkouts/create) endpoint. ## Processing Request with Payment Widget The [SumUp Payment Widget](/online-payments/checkouts/card-widget/) securely collects card details and processes checkouts while handling consent collection and 3D Secure authentication. Once you have the checkout ID from the previous step, mount the Payment Widget on your website and pass the ID as `checkoutId`. ```html
``` Upon mounting the Payment Widget with a recurring purpose checkout, you should see the following screen: Card on file with Payment Widget The customer enters their card details, consents to storing them, and completes the checkout in the Payment Widget. The card details are sent directly to SumUp and do not pass through your server. If the previous operation is successful, and the card is stored with the **Save for future payments option**, a `payment_instrument` object containing a `token` representing the card is created (AKA tokenized card) for this customer. ```json "payment_instrument": { "token": "6878cb7f-6515-47bf-bdd9-1408d270fdce" } ``` At any time, you can fetch the list of tokenized cards of a customer by requesting them via [the list payment instruments](/api/customers/list-payment-instruments) endpoint. ```bash curl -X GET \ "https://api.sumup.com/v0.1/customers/${CUSTOMER_ID}/payment-instruments" \ -H "Authorization: Bearer $SUMUP_API_KEY" \ -H "Content-Type: application/json;charset=UTF-8" ``` ```ts const instruments = await client.customers.listPaymentInstruments("MYCUSTOMERID-123"); ``` ```csharp var instruments = await client.Customers.ListPaymentInstrumentsAsync("MYCUSTOMERID-123"); ``` ```java var instruments = client.customers().listPaymentInstruments("MYCUSTOMERID-123"); ``` ```go instruments, err := client.Customers.ListPaymentInstruments(ctx, "MYCUSTOMERID-123") ``` ```py instruments = client.customers.list_payment_instruments("MYCUSTOMERID-123") ``` ```rust let instruments = client .customers() .list_payment_instruments("MYCUSTOMERID-123") .await?; ``` ```php $instruments = $sumup->customers->listPaymentInstruments('MYCUSTOMERID-123'); ``` ## Retrieving Tokenized Card Having successfully processed the checkout, a token representing the payment instrument (card) is created. You can now [retrieve the checkout](/api/checkouts/get) to find this token within a `payment_instrument` object for later recurrent payment. Example response: ```json { "id": "cd36780e-f43d-4f22-1i9e-e32a1a1bafc8", "checkout_reference": "0BYNWLYC7KV", "amount": 3.51, "currency": "EUR", ... "payment_instrument": { "token": "2fa27578-e765-5dbh-aa97-d45d3d6cdfbb" } } ``` ## Processing Recurring Payments Having tokenized the customer's card, you can now process recurring payments by referencing the saved token and the associated customer. Both `token` and `customer_id` fields are required. 1. [Create a checkout](/api/checkouts/create) again. This time, it's for the actual payment. The previous checkout was for tokenizing the card only. 2. Process the checkout. Make sure to pass the following data (`installments` is only valid for the Brazilian market): ```json { "payment_type": "card", "installments": 1, "token": "{{CARD_TOKEN}}" "customer_id": "{{CUSTOMER_ID}}", } ``` ## What's Next? You may be interested in the following resources related to Online Payments: - [Handling Refunds](/online-payments/guides/refund) - [Response Handling](/online-payments/guides/response-handling) # Payment Methods > Learn which SumUp online payment methods you can offer, how availability works, and which integration path to start with. import Country from "@components/content/Country.astro"; import PaymentMethodTitle from "@components/content/PaymentMethodTitle.astro"; SumUp supports cards, wallets, bank redirects, bank debits, real-time payment methods, vouchers, and buy now, pay later payment methods. Use this page to understand which payment methods SumUp can offer, how they behave in a checkout, and where to start your integration. If you're deciding what to build first, start with [Hosted Checkout](/online-payments/checkouts/hosted-checkout/) for the fastest launch, or [Payment Widget](/online-payments/checkouts/card-widget/) if you want an embedded checkout experience. Payment method families: - [Cards](#cards) - [Wallets](#wallets) - [Bank redirects](#bank-redirects) - [Bank debits](#bank-debits) - [Real-time payments](#real-time-payments) - [Vouchers](#vouchers) ## Before You Start The payment methods you can offer depend on more than the payment method itself. In practice, availability depends on your merchant setup and on the specific checkout you create. - Merchant country and onboarding status determine which methods can be enabled for your account. - Checkout currency, amount, and product can change the set of methods returned for a specific checkout. - Some methods redirect the customer away from your site or return payment artifacts such as QR codes or vouchers instead of completing immediately. Treat the payment methods returned for a checkout as the source of truth for that checkout. ## Cards Cards are the baseline online payment option. For Europe, the United Kingdom, and Chile, SumUp supports the following card schemes. Brazil also supports Elo and some additional niche local card schemes. Cards are the simplest place to start if you want broad coverage with a single integration. For most websites, use [Hosted Checkout](/online-payments/checkouts/hosted-checkout/), [Payment Widget](/online-payments/checkouts/card-widget/), or [Swift Checkout](/online-payments/checkouts/swift-checkout/), depending on how much checkout UI you want to own. **Availability:** [Visa](https://www.visa.com/) is one of the most widely accepted global card networks for online debit and credit card payments. **Availability:** [Visa Electron](https://www.visa.com/) is a Visa debit card product commonly used for consumer card payments in supported markets. **Availability:** [V Pay](https://www.visa.co.uk/pay-with-visa/find-a-card/v-pay.html) is Visa's European debit card scheme designed for regional card acceptance. **Availability:** [Mastercard](https://www.mastercard.com/) is a global card network used for both credit and debit card payments. **Availability:** [Maestro](https://www.mastercard.com/) is Mastercard's debit card brand for everyday consumer payments. **Availability:** [American Express](https://www.americanexpress.com/) is a global card network widely used for consumer and business card payments. **Availability:** [Discover](https://www.discover.com/) is an international card network that can be used for online card payments in supported markets. **Availability:** [JCB](https://www.global.jcb/en/) is a global card network originating in Japan and accepted for online payments in supported regions. **Availability:** [Elo](https://www.elo.com.br/) is a Brazilian card scheme supported for online payments in Brazil. Additional niche local card schemes may also be supported. ## Wallets Wallets provide a faster checkout experience by reusing saved payment details or wallet balances. Wallets are useful when you want faster checkout on mobile and supported browsers. Apple Pay and Google Pay can be offered through [Payment Widget](/online-payments/checkouts/card-widget/), through the [Swift Checkout SDK](/online-payments/checkouts/swift-checkout/), or through their dedicated direct integration guides. **Availability:** [Apple Pay](https://www.apple.com/apple-pay/) is Apple's wallet-based checkout experience for Safari and Apple devices. **Availability:** [Google Pay](https://pay.google.com/about/) is Google's wallet checkout option for supported browsers, devices, and Android surfaces. **Availability:** [PayPal](https://www.paypal.com/) lets customers authorize payments using their PayPal account instead of entering card details directly. **Availability:** [SumUp Pay](https://www.sumup.com/) is SumUp's own payment experience for returning customers within the SumUp ecosystem. **Availability:** [BANCOMAT Pay](https://www.bancomat.it/en/bancomat-pay/) is an Italian account-linked mobile payment method operated by BANCOMAT. ## Bank Redirects Bank redirect methods send the customer to their bank or local payment network to approve the payment. These methods usually require you to handle a pending status and send the customer through an additional authorization step. Payment Widget handles this checkout experience for the customer. **Availability:** [Bancontact](https://bancontact.com/en) is Belgium's domestic online payment method for redirect-based checkout. **Availability:** [Blik](https://blik.com/en) is a Polish payment method that lets customers confirm payments through their banking app. **Availability:** [EPS](https://www.eps-ueberweisung.at/) is an Austrian online bank redirect method commonly used for domestic ecommerce payments. **Availability:** [iDeal](https://www.ideal.nl/en/) is the Netherlands' most widely used online banking payment method for ecommerce. **Availability:** [MyBank](https://www.mybank.eu/) is a European online bank payment scheme that redirects customers to authorize the transaction with their bank. **Availability:** [Przelewy24](https://www.przelewy24.pl/en) is a Polish online bank redirect method and payment network for local ecommerce checkout. **Availability:** [TWINT](https://www.twint.ch/en/) is a Swiss mobile payment method that supports wallet-style and bank-linked payments. ## Bank Debits Bank debit methods collect funds directly from the customer's bank account. Bank debit methods can require additional customer details depending on the checkout flow. ## Real-Time Payments Real-time payment methods confirm funds immediately and are commonly used for local account-to-account payment flows. Some real-time methods return payment artifacts such as QR codes instead of using a browser redirect. **Availability:** [PIX](https://www.bcb.gov.br/estabilidadefinanceira/pix) is Brazil's instant payment system for real-time account-to-account transfers. **Availability:** [QR Code powered by PIX](https://www.bcb.gov.br/estabilidadefinanceira/pix) lets customers complete a PIX payment by scanning a generated QR code. ## Vouchers Voucher-based methods generate a payment artifact that the customer uses to complete the purchase. Voucher methods are asynchronous by nature and rely on a payment artifact that the customer uses to complete the payment. **Availability:** [Boleto](https://portal.febraban.org.br/pagina/3166/33/en/) is a Brazilian voucher-based payment method where the customer pays using a generated boleto document or barcode. :::tip Availability still depends on merchant setup, checkout product, and account configuration. For implementation details, see [Alternative Payment Methods](/online-payments/apm/) and the [Payment Widget](/online-payments/checkouts/card-widget/). ::: # Plugins > Overview of SumUp plugins for third-party platforms. import PluginsList from '@components/OnlinePayments/PluginsList'; These plugins enable quick SumUp payment integration on PrestaShop, Wix, WooCommerce, Medusa, and Vendure requiring only your API key and merchant information to start. Select a plugin of interest for further, detailed instructions. # Medusa > Accept SumUp payments in Medusa with the SumUp plugin for Medusa v2. import { LinkButton } from "@astrojs/starlight/components"; The [SumUp plugin for Medusa](https://github.com/sumup/sumup-plugin-medusa) adds SumUp as a payment provider for [Medusa v2](https://medusajs.com/). It lets your Medusa backend create and manage SumUp online checkouts while keeping your SumUp credentials on the server side. The plugin supports: - Hosted Checkout, where the customer is redirected to a SumUp-hosted payment page - Payment Widget, where your storefront mounts the SumUp Payment Widget using a checkout created by Medusa - Refunds through SumUp transactions - Medusa payment webhooks for asynchronous status updates :::note The plugin supports SumUp online payment flows only. It does not support terminal or other card-present integrations. ::: View Medusa Plugin Repository ## Prerequisites - Active [SumUp account](https://me.sumup.com) - SumUp [API key](/tools/authorization/api-keys/#create-an-api-key) - SumUp merchant code - Medusa `v2.15.x` - A Medusa backend with the payment module enabled Before going live, make sure your SumUp account is fully verified and your business model is supported according to our [allowed businesses article](https://help.sumup.com/en-GB/articles/3G8ZHjdgFZjmKWOmDWS52m). ## Install the Plugin Install the package in your Medusa project: ```bash yarn add @sumup/medusa-plugin ``` ## Configure Medusa Register the plugin and payment provider in `medusa-config.ts`: ```ts import { defineConfig } from "@medusajs/framework/utils"; export default defineConfig({ plugins: [ { resolve: "@sumup/medusa-plugin", options: {}, }, ], modules: [ { resolve: "@medusajs/medusa/payment", options: { providers: [ { resolve: "@sumup/medusa-plugin/providers/sumup", id: "sumup", options: { apiKey: process.env.SUMUP_API_KEY, merchantCode: process.env.SUMUP_MERCHANT_CODE, checkoutMode: "hosted", returnUrl: `${process.env.MEDUSA_BACKEND_URL}/hooks/payment/sumup_sumup`, redirectUrl: `${process.env.STOREFRONT_URL}/checkout/sumup/return`, }, }, ], }, }, ], }); ``` After your application starts, enable the provider for the relevant region in Medusa Admin. For the service identifier `sumup` and provider `id` `sumup`, the resulting Medusa payment provider identifier is `pp_sumup_sumup`. ## Configuration Options The plugin accepts the following provider options: | Option | Required | Description | | --- | --- | --- | | `apiKey` | Yes | SumUp API key or access token. Keep it server-side. | | `merchantCode` | Yes | SumUp merchant code that receives the payment. | | `checkoutMode` | No | Checkout mode: `hosted` or `widget`. Defaults to `hosted`. | | `returnUrl` | No | Backend webhook URL. For provider `id: "sumup"`, use `/hooks/payment/sumup_sumup`. | | `redirectUrl` | No | Storefront URL used after redirect or Strong Customer Authentication flows. | | `paymentDescription` | No | Default SumUp checkout description. | | `timeout` | No | SumUp SDK request timeout in milliseconds. | | `maxRetries` | No | SumUp SDK retry count. | You can also override `checkout_mode`, `description`, `return_url`, `redirect_url`, and `checkout_reference` per payment session through provider data. ## Choose a Checkout Flow ### Hosted Checkout With `checkoutMode: "hosted"`, the plugin creates a SumUp checkout with Hosted Checkout enabled and stores the returned `hosted_checkout_url` in the Medusa payment session. Your storefront should redirect the customer to that URL to complete the payment. Use your backend state as the source of truth. The redirect alone should not be treated as proof of a successful payment. ### Payment Widget With `checkoutMode: "widget"`, the plugin creates a SumUp checkout and stores the returned `checkout_id` in the payment-session data. Your storefront is then responsible for loading and mounting the SumUp widget and asking the backend to re-check the payment state after a successful widget response. If you need a lower-level widget implementation reference, see the [Payment Widget guide](/online-payments/checkouts/card-widget/). ## Webhooks Medusa provides a built-in webhook listener route for payment providers at: ```text /hooks/payment/[identifier]_[provider] ``` For this plugin, with service identifier `sumup` and provider `id` `sumup`, the webhook URL is: ```text https://your-medusa-backend.com/hooks/payment/sumup_sumup ``` The plugin receives the webhook payload, retrieves the checkout from SumUp, maps the result to a Medusa payment action, and returns the payment session reference back to Medusa. ## What the Plugin Stores The payment-session data returned by the provider includes: - `checkout_id` - `checkout_reference` - `checkout_mode` - `hosted_checkout_url` for hosted flows - `transaction_id` and `transaction_code` when available - `merchant_code` - `amount` and `currency` ## Sandbox Checklist Before enabling the plugin in production, verify the following in a sandbox environment: - One successful Hosted Checkout payment - One successful Payment Widget payment - At least one webhook-driven payment update - One full refund and one partial refund - SumUp's deliberate failure path with amount `11` - Expired or canceled checkouts mapping cleanly back into Medusa session state :::note Minimal storefront and Docker example projects are available in the plugin repository if you want a working reference implementation. ::: # PrestaShop > Accept SumUp payments with the PrestaShop plugin. import { LinkButton } from '@astrojs/starlight/components'; To use PrestaShop with SumUp, download the SumUp Payment module plugin, which requires configuration in your SumUp dashboard. Download PrestaShop Plugin ## Prerequisites You will need an active [SumUp account](https://me.sumup.com). As an authorized Payment Institution by the Central Bank of Ireland, SumUp must verify your identity and business ownership. Please make sure your [business model is supported by SumUp](https://help.sumup.com/en-GB/articles/3G8ZHjdgFZjmKWOmDWS52m). :::note Currently, Alternative Payment Methods (APMs) are not available in SumUp plugins. We are working to support APMs soon. ::: ## Installation 1. Follow [the register application guide](/tools/authorization/oauth/#register-an-oauth-application) to obtain the client credentials for your app. 2. Download the client credentials file. 3. Upload the JSON to the **Module Configuration** page in PrestaShop Backoffice. 4. After SumUp account verification, [contact us](/contact) to enable online payments scope for your PrestaShop online store. ![SumUp Payment Gateway for PrestaShop](/img/guides/prestashop_step_5.png) Once you receive a confirmation from SumUp, you’re fully set-up! Note that minimum transaction amount is 1 EUR (or equivalent). :::note Still need help? Contact our [customer service](https://me.sumup.com/en-gb/support) for assistance. ::: # Vendure > Accept SumUp payments in Vendure with the SumUp plugin. import { LinkButton } from "@astrojs/starlight/components"; The [SumUp plugin for Vendure](https://github.com/sumup/sumup-plugin-vendure) adds SumUp as a payment integration for [Vendure](https://vendure.io/). It creates SumUp checkouts from Vendure's payment flow while keeping your SumUp credentials on the server side. The plugin supports: - Hosted Checkout, where the customer is redirected to a SumUp-hosted payment page - Widget-oriented storefront integrations that use a returned `checkoutId` - Webhook-driven payment updates through Vendure's payment flow :::note The plugin supports SumUp online payment flows only. It does not support terminal or other card-present integrations. ::: View Vendure Plugin Repository View Vendure Plugin Docs ## Prerequisites - Active [SumUp account](https://me.sumup.com) - SumUp [API key](/tools/authorization/api-keys/#create-an-api-key) - SumUp merchant code - Vendure `^3.6.4` - A Vendure server with payment methods enabled Before going live, make sure your SumUp account is fully verified and your business model is supported according to our [allowed businesses article](https://help.sumup.com/en-GB/articles/3G8ZHjdgFZjmKWOmDWS52m). ## Install the Plugin Install the package in your Vendure project: ```bash npm install @sumup/vendure-plugin ``` ## Configure Vendure Register the plugin and payment handler in your Vendure config: ```ts import { VendureConfig } from "@vendure/core"; import { SumUpPlugin, sumUpPaymentHandler, } from "@sumup/vendure-plugin"; export const config: VendureConfig = { plugins: [ SumUpPlugin.init({ apiKey: process.env.SUMUP_API_KEY!, merchantCode: process.env.SUMUP_MERCHANT_CODE!, checkoutMode: "hosted", returnUrl: "https://your-vendure.example/payments/sumup/webhook", redirectUrl: "https://storefront.example/checkout/sumup/return", }), ], paymentOptions: { paymentMethodHandlers: [sumUpPaymentHandler], }, }; ``` `returnUrl` should be a publicly reachable URL that SumUp can call with checkout status updates. In most setups that should be your Vendure server's `/payments/sumup/webhook` route. ## Create the Payment Method Create a payment method in the Vendure Admin UI with: - `Code`: `sumup` - `Handler`: `sumup` Optional handler arguments: - `merchantCode` - `checkoutMode` - `returnUrl` - `redirectUrl` - `paymentDescription` Global defaults can be defined in `SumUpPlugin.init()` and overridden per payment method when needed. ## Storefront Flow Once the order is in `ArrangingPayment`, call `addPaymentToOrder` with `method: "sumup"` and any SumUp-specific metadata you need: ```graphql mutation AddPaymentToOrder { addPaymentToOrder( input: { method: "sumup" metadata: { checkout_mode: "hosted" checkout_reference: "ORDER-1001" } } ) { ... on Order { id state payments { transactionId metadata } } ... on ErrorResult { errorCode message } } } ``` The plugin stores SumUp data on the Vendure payment and exposes a safe subset through `payments[].metadata.public`. ## Choose a Checkout Flow ### Hosted Checkout Use `checkout_mode: "hosted"` or set `checkoutMode: "hosted"` in the plugin or payment-method config. After `addPaymentToOrder`, redirect the shopper to: ```text payments[].metadata.public.hostedCheckoutUrl ``` Use your backend payment state as the source of truth. The redirect alone should not be treated as proof of a successful payment. ### Widget-Oriented Flow Use `checkout_mode: "widget"` if your storefront will mount SumUp's checkout UI itself. After `addPaymentToOrder`, read: ```text payments[].metadata.public.checkoutId ``` Use that `checkoutId` in your storefront's SumUp client integration. The plugin still treats the webhook callback or a later checkout lookup as the source of truth for the final payment state. If you need a lower-level widget implementation reference, see the [Payment Widget guide](/online-payments/checkouts/card-widget/). ## Webhooks The plugin exposes a notification endpoint at: ```text POST /payments/sumup/webhook ``` When SumUp calls this endpoint, the plugin re-fetches the checkout from SumUp and updates the matching Vendure payment from the checkout state. ## Public Payment Metadata The plugin exposes these fields in `payments[].metadata.public`: | Field | Description | | --- | --- | | `checkoutId` | SumUp checkout ID | | `checkoutReference` | Merchant checkout reference sent to SumUp | | `checkoutMode` | `hosted` or `widget` | | `hostedCheckoutUrl` | Hosted Checkout URL when SumUp returns one | | `redirectUrl` | Redirect URL associated with the checkout | ## Configuration Options | Option | Required | Description | | --- | --- | --- | | `apiKey` | Yes | SumUp API key or access token. Keep it server-side. | | `merchantCode` | Yes | SumUp merchant code that receives the payment. | | `defaultLanguageCode` | No | Language used for the handler description shown in Vendure. | | `checkoutMode` | No | Default checkout mode: `hosted` or `widget`. Defaults to `hosted`. | | `returnUrl` | No | Backend callback URL used by SumUp for checkout status updates. | | `redirectUrl` | No | URL the shopper is sent to after redirect-based payment flows. | | `paymentDescription` | No | Default SumUp checkout description. | | `timeout` | No | SumUp SDK request timeout in milliseconds. | | `maxRetries` | No | SumUp SDK retry count. | | `supportedCurrencies` | No | Override the built-in supported currency allowlist. | | `client` | No | Inject a custom SumUp client implementation. Useful for tests. | ## Payment State Mapping The plugin maps SumUp checkout state to Vendure payment state like this: - Successful transaction or `PAID` checkout -> `Settled` - `PENDING` -> `Authorized` - `FAILED` -> `Declined` - `EXPIRED` -> `Cancelled` - Anything else -> `Created` ## Sandbox Checklist Before enabling the plugin in production, verify the following in a sandbox environment: - One successful Hosted Checkout payment - One successful widget-oriented payment flow - At least one webhook-driven payment update - SumUp's deliberate failure path with amount `11` - Expired or canceled checkouts mapping cleanly back into Vendure payment state :::note The plugin does not add Admin UI extensions or extend Vendure's GraphQL schema. It uses the standard `addPaymentToOrder` payment metadata flow. ::: # Wix > Accept SumUp payments on your Wix online store. Connect your [Wix online store](https://wix.com) dashboard to SumUp for secure payment processing through our payment gateway, as explained in this guide. :::note New onboarding for the Wix integration has been temporarily paused since **March 2025**. If you’re already using the integration, you can continue processing payments. For updates or alternatives, contact us via the [contact form](/contact). ::: ## Prerequisites - Active [SumUp account](https://me.sumup.com). If you don't have one yet, sign up on [our website](https://me.sumup.com/signup). As an authorized Payment Institution by the Central Bank of Ireland, SumUp must verify your identity and business ownership. - Business model supported by SumUp, according to our [allowed businesses article](https://help.sumup.com/en-GB/articles/3G8ZHjdgFZjmKWOmDWS52m). - Wix online store. The Wix integration supports the following Alternative Payment Methods (APMs): iDeal (Netherlands), Bancontact (Belgium), P24 (Poland), EPS (Austria). Apple Pay and Google Pay are currently unavailable. ## Installation 1. First, create your secret API Key. [See this article](/tools/authorization/api-keys/#create-an-api-key) for details. Copy your key before proceeding. 2. In the Wix dashboard, go to **Settings** > **Accept payments**. 3. Select **SumUp**, paste your secret API Key in **Account Information**, and **Save**. That's it! You can now start accepting payments through SumUp on your Wix online store. If you have any questions or encounter any issues, contact our [customer service](https://me.sumup.com/en-gb/support) team. # WooCommerce > Accept SumUp payments with the WooCommerce plugin. import { LinkButton } from "@astrojs/starlight/components"; The [SumUp Payment Gateway for WooCommerce](https://wordpress.org/plugins/sumup-payment-gateway-for-woocommerce/) enables payments on WordPress sites without coding, enabling your customizations and providing your customers the convenience of securely buying products from your website without being redirected to other pages. The plugin supports major cards (Visa, Mastercard, Amex, Diners, Discover, JCB) via embedded forms. Transactions are processed through the SumUp payment platform with [transaction history provided in the SumUp Dashboard](https://me.sumup.com/sales/transactions). :::note The SumUp WooCommerce plugin is SCA ready and compliant with PCI standards. ::: Go to plugin page ## Prerequisites - Active [SumUp account](https://me.sumup.com). If you don't have one yet, sign up on [our website](https://me.sumup.com/signup). As an authorized Payment Institution by the Central Bank of Ireland, SumUp must verify your identity and business ownership. - [Review allowed businesses](https://help.sumup.com/hc/en-gb/articles/115008338707-Restricted-businesses) before [signing up](https://me.sumup.com). ## Installing the Plugin ### Automatic Installation The automatic installation is the easiest option, as WordPress handles the file transfer and you don't need to leave your web browser. 1. Install the plugin via the **Plugins** section in the WordPress Dashboard. 2. Click on **Add new** and search for **SumUp Payment Gateway for WooCommerce**. 3. Click on the **Install Now** button. 4. Click **Activate** to active the plugin. ### Manual Installation 1. [Download our plugin](https://wordpress.org/plugins/sumup-payment-gateway-for-woocommerce/). 2. Upload it to your web server using FTP. See [WordPress codex](https://wordpress.org/support/article/managing-plugins/#manual-upload-via-wordpress-admin) for details on how to do this. Before setting up the plugin, create your client credentials. ## Integration Options For plugin versions `2.5` or later, both a [simple](#simple-integration) and [advanced](#advanced-integration) integration flows are available. If you are using a plugin version below `2.5`, follow the steps in our [advanced integration guide](#advanced-integration). ### Simple Integration Available for plugin versions above `2.5`. 1. Click **Connect account** to initiate the lightweight integration flow (redirects to SumUp Dashboard). 2. In your SumUp Dashboard, click on **Start setup** to generate your production API keys. Once the flow is initiated, we will take care of generating live API keys for your SumUp account. When the flow completes successfully, they will become available to your WordPress shop. At this point, you can start accepting payments through SumUp on your WordPress shop. :::note The [Online Payments settings page](https://me.sumup.com/settings/online-payments) in the SumUp Dashboard, allows you to view your plugin connections and manage payment method settings. ::: ![SumUp Payment Gateway for WooCommerce plugin settings](/img/guides/woocommerce_plugin.png) ### Advanced Integration 1. Once the plugin is activated, click **Advanced version**. 2. [Create your API Key](/tools/authorization/api-keys/#create-an-api-key). 3. Enter SumUp credentials (API Key, email, and merchant code) and settings. ## Additional Configuration - Enable the SumUp Payment Gateway - Set customer-facing title/description - Apply an optional payment method description, visible by your customers - Match shop currency to SumUp account - Require ZIP code from your customers. **Mandatory for US merchants** - We recommend enabling the logging option for better troubleshooting should any issues occur (logs can be found in **WooCommerce** > **Status** > **Logs**) - Choose between popup or embedded payment form with the **Open Payment in modal?** option ### Update Your Website Before accepting payments through SumUp, your website should display the following information: - Business & product information - Delivery, cancellation & return/refund policy - Payment & billing process - All prices must have the respective currency prefix - Privacy policy - Security policy :::note We recommend configuring a "Thank You" page for successful checkouts, according to [WooCommerce official standards](https://docs.woocommerce.com/document/woocommerce-custom-thank-you-pages/). ::: ## Configuration for Legacy Plugin (Version Older than 2.5) ### Create Your Client Credentials To create client credentials you must have an active [SumUp account](https://me.sumup.com) with completed [account details](https://me.sumup.com/account). Your account has successfully completed the onboarding process, and you have received the `payments` scope activation. If you don't have the `payments` scope activated yet, [contact us](/contact) for assistance. :::caution SumUp aims to respond to all [contact queries](/contact) within 24 hours, Monday through Friday. ::: Once you ensure you've met the above requirements, you can proceed with our [Register application guide](/tools/authorization/oauth/#register-an-oauth-application) to set up your client credentials. ## Plugin Configuration Now that you have created your client credentials and installed the plugin, you can proceed with configuration. In WordPress Dashboard, go to **Plugins** `. **Settings** under the SumUp WooCommerce plugin. You will find the following customization options: - Enable the SumUp Payment Gateway - Apply custom title of the payment method, visible by your customers - Apply an optional payment method description, visible by your customers - Apply your shop currency corresponding to the one set in your SumUp account - **Client ID** and **Client Secret** of your application. Both are located in the JSON file you created in the [Create your client credentials step](#create-your-client-credentials), in the following key-value pair: ```json { "id": "CCCFAXYD", "name": "My Online Store Name", "client_id": "fOcmczrYtYMJ7Li5GjMLLcUeC9dN", "client_secret": "717bd571b54297494cd7a79b491e8f2c1da6189c4cc2d3481380e8366eef539c", "application_type": "web", "redirect_uris": ["https://mywebsite.com/callback"] } ``` - The email address of your SumUp merchant account - The merchant code associated with your SumUp account - Require ZIP code from your customers. **Mandatory for US merchants** - We recommend enabling logs for better troubleshooting, should any issues occur (Logs can be accessed in **WooCommerce** > **Status** > **Logs**) # React Native Checkout SDK > Step-by-step guide for integrating the SumUp React Native Payment SDK, from prerequisites to checkout creation and mounting the payment sheet. import { Tabs, TabItem } from '@astrojs/starlight/components'; import Image from '@components/content/Image.astro'; SumUp's React Native Payment SDK provides a payment sheet that is displayed on top of your app. It collects user payment details, confirms a payment, and saves a card for future usage. Moreover, it allows a user to use Apple Pay or Google Pay to process payments. Challenge screen ## Integration ### Before You Begin Here are the things that you need in order to complete the steps in this guide: - You have a merchant account with [SumUp](https://me.sumup.com/login) and have already filled in your [account details](https://me.sumup.com/account). - For a **sandbox merchant account** reach out to our support team through this [contact form](/contact). - You have [registered your client application](/tools/authorization/oauth/#register-an-oauth-application) with SumUp. - You have a valid access token obtained via the [Authorization code flow](/tools/authorization/oauth/#authorization-code-flow). - The restricted `payment_instruments` scope is enabled for your client application. If it isn't enabled, [contact us](/contact) and request it. ### Create a Checkout Initializing the SDK works by passing it a `checkout_id`. To [create a checkout](/api/checkouts/create) on your backend make the following request: ```bash curl --request POST \ --url https://api.sumup.com/v0.1/checkouts \ --header "Authorization: Bearer $SUMUP_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "checkout_reference": "44ea5096-b83f-46e1-9323-fe82a8cb7eb5", "currency": "SEK", "amount": 9.99, "description": "Order #1234", "merchant_code": "MXXXXXXX", "return_url": "https://example.com", "redirect_url": "https://sumup.com" }' ``` ```ts const checkout = await client.checkouts.create({ checkout_reference: "44ea5096-b83f-46e1-9323-fe82a8cb7eb5", amount: 9.99, currency: "SEK", merchant_code: "MXXXXXXX", description: "Order #1234", return_url: "https://example.com", redirect_url: "https://sumup.com", }); ``` ```csharp var checkout = await client.Checkouts.CreateAsync(new CheckoutCreateRequest { CheckoutReference = "44ea5096-b83f-46e1-9323-fe82a8cb7eb5", Amount = 9.99f, Currency = Currency.Sek, MerchantCode = "MXXXXXXX", Description = "Order #1234", ReturnUrl = "https://example.com", RedirectUrl = "https://sumup.com", }); ``` ```java var checkout = client.checkouts().createCheckout( CheckoutCreateRequest.builder() .checkoutReference("44ea5096-b83f-46e1-9323-fe82a8cb7eb5") .amount(9.99f) .currency(Currency.SEK) .merchantCode("MXXXXXXX") .description("Order #1234") .returnUrl("https://example.com") .redirectUrl("https://sumup.com") .build() ); ``` ```go description := "Order #1234" returnURL := "https://example.com" redirectURL := "https://sumup.com" checkout, err := client.Checkouts.Create(ctx, sumup.CheckoutsCreateParams{ CheckoutReference: "44ea5096-b83f-46e1-9323-fe82a8cb7eb5", Amount: 9.99, Currency: sumup.CurrencySEK, MerchantCode: "MXXXXXXX", Description: &description, ReturnURL: &returnURL, RedirectURL: &redirectURL, }) ``` ```py from sumup.checkouts.resource import CreateCheckoutBody checkout = client.checkouts.create( CreateCheckoutBody( checkout_reference="44ea5096-b83f-46e1-9323-fe82a8cb7eb5", amount=9.99, currency="SEK", merchant_code="MXXXXXXX", description="Order #1234", return_url="https://example.com", redirect_url="https://sumup.com", ) ) ``` ```rust let checkout = client .checkouts() .create(Some(sumup::resources::checkouts::CheckoutCreateRequest { checkout_reference: "44ea5096-b83f-46e1-9323-fe82a8cb7eb5".into(), amount: 9.99, currency: sumup::resources::checkouts::Currency::SEK, merchant_code: "MXXXXXXX".into(), description: Some("Order #1234".into()), return_url: Some("https://example.com".into()), redirect_url: Some("https://sumup.com".into()), customer_id: None, purpose: None, id: None, status: None, date: None, valid_until: None, transactions: None, })) .await?; ``` ```php $checkout = $sumup->checkouts->create([ 'checkout_reference' => '44ea5096-b83f-46e1-9323-fe82a8cb7eb5', 'currency' => 'SEK', 'amount' => 9.99, 'description' => 'Order #1234', 'merchant_code' => 'MXXXXXXX', 'return_url' => 'https://example.com', 'redirect_url' => 'https://sumup.com', ]); ``` The SDK will process the checkout once a customer provides payment details. If payment details aren't passed an error will be received. ## Set up SDK Install the npm module by one of the following commands: ```bash npm i sumup-react-native-alpha npm i react-native-webview ``` ```bash yarn add sumup-react-native-alpha yarn add react-native-webview ``` You need to install `react-native-localization` to automatically detect the user system language. ```bash npm i react-native-localization ``` ```bash yarn add react-native-localization ``` If you don't need it, please provide the language field in the `initPaymentSheet` function. ```javascript await initPaymentSheet({ checkoutId, language: 'en', }); ``` Next, install the native modules. ```bash cd ios pod install ``` SDK should be initialized by wrapping your payment screen into SumUpProvider. This component requires an `apiKey` you can create in the [API Keys settings](/tools/authorization/api-keys/). ```javascript import { SumUpProvider } from 'sumup-react-native-alpha'; export default function App() { return ( ); } ``` ## Provide Payment Details Before showing the payment sheet, it needs to be initialized. Call `initPaymentSheet` with the parameters like in example below: ```js import React, { useEffect } from "react"; import { View, Alert } from "react-native"; import { useSumUp } from "sumup-react-native-alpha"; export default function MainScreen() { const { initPaymentSheet } = useSumUp(); const initSumUpPaymentSheet = async () => { const { error } = await initPaymentSheet({ checkoutId: "...", customerId: "...", language: "en", // en or sv are supported }); if (error) { Alert.alert( error.status, error.status === "failure" ? error.message : undefined ); } else { Alert.alert("Payment Sheet was configured"); } }; useEffect(() => { initSumUpPaymentSheet(); }, []); ... ``` **Required** fields for `initPaymentSheet`: - `checkoutId` - described in section [Create a checkout](/online-payments/sdks/react-native/#create-a-checkout). *Optional*: - `customerId` - used for saving cards for future usage. - `language` - English and Sweden are supported (if undefined, react-native-localization will be used to check user device language). ## Show Payment Sheet After initialization a payment sheet can be shown. When a user presses a button, you can show it by calling `presentPaymentSheet()`. After a user completes a payment, this function will return a callback. If any errors take place, the callback will contain an error field with the details. ```js ... const showPaymentSheet = async () => { const { error } = await presentPaymentSheet(); if (error) { Alert.alert( error.status, error.status === "failure" ? error.message : undefined ); } else { Alert.alert("Payment successfully was processed"); } }; return (