# Mada for web
Accept Mada payments through Apple Pay on your website with [Flow](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website.md), our pre-built, customizable payment user interface.
Flow enables you to accept payments using Checkout.com's global network of payment methods with a single integration.
> **Information**
>
> You can only process Mada payments through Apple Pay within Saudi Arabia. Outside of Saudi Arabia you must enforce the use of the Visa or Mastercard networks instead.
>
>
> For more information, see [Mada](https://www.checkout.com/docs/payments/add-payment-methods/mada.md#Accept_Mada_cards_outside_Saudi_Arabia).
Set up your client-side and server-side configuration to integrate with Checkout.com's payment gateway and enable payments on your website.
---
## How it works
1. The customer lands on the checkout page.
2. You perform a server-side request to create a payment session.
3. You use the payment session data on the client-side to mount Flow.
4. Flow displays the card or Apple Pay payment method to the customer, where they can choose to pay with their Mada card.
5. When the customer clicks the _Pay_ option, Flow performs a payment request and handles any additional actions. For example, additional actions required for [3D Secure (3DS)](https://www.checkout.com/docs/payments/authenticate-payments/3d-secure.md) authentication, or a third-party payment page redirect.
6. You receive a webhook notifying you of the payment status.
---
## Before you start
To offer Apple Pay with Flow, you must:
- Contact your account manager to onboard a custom domain with Apple Pay.
- Comply with the Apple Pay [payment method rules](https://www.checkout.com/legal/payment-methods-rules).
Additionally, to accept Mada card payments, you must:
- Obtain a merchant ID from a Saudi Arabian card acquirer.
- Capture the full authorization amount after a successful authorization. Partial captures and partial authorizations are not supported.
Make sure you have a [test account](https://www.checkout.com/get-test-account) with Checkout.com.
Create a [public key and a secret key](https://www.checkout.com/docs/developer-resources/api/manage-api-keys/api-keys.md) from the [Dashboard](https://dashboard.checkout.com), with the following key scopes:
- Public key – `payment-sessions:pay` and `vault-tokenization`
- Secret key – `payment-sessions`
To receive webhooks for the [payment events](https://www.checkout.com/docs/developer-resources/event-notifications/event-types.md#Gateway), [configure your webhook server](https://www.checkout.com/docs/developer-resources/event-notifications/receive-webhooks/configure-your-webhook-server.md).
> **Information**
>
> Some operating systems may not fully support Apple Pay if you integrate Flow within a WebView.
### Content Security Policy
If you have a Content Security Policy (CSP) on your website, Checkout.com requires the following directives:
```
connect-src, https://*.checkout.com
frame-src, https://*.checkout.com
script-src, https://*.checkout.com
img-src, https://*.checkout.com
```
---
## Step 1: Create a new Payment Session `Server side`
When the customer is ready to pay, you must send a server-side request to securely create a `PaymentSession` object. The `PaymentSession` contains the information required to handle all steps of the payment flow.
> **Information**
>
> For the full API specification, see the [API reference](https://api-reference.checkout.com/tag/Flow/#operation/CreatePaymentSession).
> **Information**
>
> Your base URL's `{prefix}` value is unique to your account and environment. To learn how to retrieve your base URLs for the sandbox and production environments, see [API endpoints](https://www.checkout.com/docs/developer-resources/api/api-endpoints.md).
**Production**
`POST` `https://{prefix}.api.checkout.com/payment-sessions`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payment-sessions`
### Request example
```json
{
"amount": 1000,
"currency": "SAR",
"reference": "ORD-123A",
"display_name": "Online shop",
"payment_type": "Regular",
"billing": {
"address": {
"country": "SA"
}
},
"customer": {
"name": "Jia Tsang",
"email": "jia.tsang@example.com"
},
"items": [
{
"reference": "0001",
"name": "Gold Necklace",
"quantity": 1,
"unit_price": 1000
}
],
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
```
### Response example
```json
{
"id": "ps_2Un6I6lRpIAiIEwQIyxWVnV9CqQ",
"payment_session_secret": "pss_9823241e-2cec-4c98-b23d-7b29ow4e2e34",
"payment_session_token": "YmFzZTY0:eyJpZCI6InBzXzJVbjZJNmxScElBaUlFd1FJeXhXVm5WOUNxUSIsImFtb3VudCI6MTAwMCwibG9jYWxlIjoiZW4tR0IiLCJjdXJyZW5jeSI6IkdCUCIsInBheW1lbnRfbWV0aG9kcyI6W3sidHlwZSI6ImNhcmQiLCJjYXJkX3NjaGVtZXMiOlsiVmlzYSIsIk1hc3RlcmNhcmQiLCJBbWV4Il19XSwicmlzayI6eyJlbmFibGVkIjp0cnVlfSwiX2xpbmtzIjp7InNlbGYiOnsiaHJlZiI6Imh0dHBzOi8vYXBpLnNhbmRib3guY2hlY2tvdXQuY29tL3BheW1lbnQtc2Vzc2lvbnMvcHNfMlVuNkk2bFJwSUFpSUV3UUl5eFdWblY5Q3FRIn19fQ==",
"_links": {
"self": {
"href": "https://{prefix}.api.sandbox.checkout.com/payment-sessions/ps_2Un6I6lRpIAiIEwQIyxWVnV9CqQ"
}
}
}
```
---
## Step 2: Initialize and mount Flow `Client side`
You can install the `@checkout.com/checkout-web-components` package via npm:
```bash
npm install @checkout.com/checkout-web-components --save
```
Alternatively, you can load the package directly via a script:
```html
```
> **Note**
>
> To remain PCI compliant, you should only ever load the script directly from `https://checkout-web-components.checkout.com`. Do not download or host the script yourself, or include it in a bundle.
The client side initializes an instance of `CheckoutWebComponents` with configuration information and the payment session data retrieved in step 1.
```javascript
// Insert your public key here
const publicKey = '{YOUR_PUBLIC_KEY}';
const checkout = await CheckoutWebComponents({
paymentSession,
publicKey,
environment: 'sandbox',
});
```
### Configuration options
You can use the following configuration options to instantiate an instance of `CheckoutWebComponents`:
| JavaScript key | Description |
| --- | --- |
| `appearance` | Allows you to customize the visual appearance of the `CheckoutWebComponents` elements. To see the customization options, refer to the [Appearance options](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/customize-your-flow-integration.md#Appearance_options) documentation. |
| `componentOptions` | Enables you to customize the options for the individual Flow components. For example, you can change the position of the cardholder field in the `card` component. To see the customization options, refer to the [component options](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/flow-library-reference/checkoutwebcomponents.md#Initialization) documentation. |
| `environment` | Sets the environment that the library should point, and send requests to. This can be one of:
- `production`
- `sandbox` |
| `locale` | Sets the customer's locale. Explicitly setting this value overrides the `locale` returned by the `PaymentSession`. To see a list of supported languages, refer to the [localization](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/add-localization-to-your-flow-integration.md) documentation. |
| `paymentSession` | The response from the `PaymentSession`.
This field is required. |
| `publicKey` | Your public API key. Your key is prefixed with `pk_`.
This field is required. |
| `translations` | Allows you to provide custom text translations for natively supported languages, or add custom text for locales and languages not natively supported by Flow. To learn how to add translations, refer to the [Add localization to your Flow integration](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/add-localization-to-your-flow-integration.md) documentation. |
Use `CheckoutWebComponents` to create a `flow` object.
```javascript
const flowComponent = checkout.create("flow");
```
Mount Flow to the website using the `mount()` method. The method takes an [Element selector](https://developer.mozilla.org/en-US/docs/Web/API/Element) or an [Element](https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors) as an argument. For example, `#flow-container` or `document.getElementById(#flow-container)`, respectively.
**Mount Flow to a Selector**
```javascript
if (await flowComponent.isAvailable()) {
flowComponent.mount('#flow-container');
}
```
**Mount Flow to an Element**
```javascript
const flowElement = document.getElementById('flow-container');
if (await flowComponent.isAvailable()) {
flowComponent.mount(flowElement);
}
```
> **Note**
>
> Embedding Flow within an iframe or onto a Shadow DOM is not supported.
---
## Step 3: Handle the payment response `Client side`
The `onPaymentCompleted` event triggers when a payment is successfully completed. You can use the event data to notify the customer of the payment status.
Add the event handler to the Flow initialization code:
```javascript
const publicKey = '{YOUR_PUBLIC_KEY}';
const checkout = await CheckoutWebComponents({
paymentSession,
publicKey,
environment: 'sandbox',
onPaymentCompleted: async (_self, paymentResponse) => {
// Handle synchronous payments
await handlePayment(paymentResponse.id);
},
});
```
If you've [configured your webhook server](https://www.checkout.com/docs/developer-resources/event-notifications/receive-webhooks/configure-your-webhook-server.md), we send a [Gateway](https://www.checkout.com/docs/developer-resources/event-notifications/event-types.md#Gateway) webhook to your server. The webhook we send depends on the status of the payment. Wait for the webhook callback before you start your order fulfillment process.
The `PaymentSession` ID is returned in the webhook payload's `data.metadata.cko_payment_session_id` field.
---
## Test the integration
To test Mada payments, use one of the following test cards:
| Card number | Card type |
| --- | --- |
| `4464043505991993` | Mada, Visa co-brand |
| `4407954943022953` | Mada, Visa co-brand |
| `5433571755811375` | Mada, Mastercard co-brand |
| `5541805721646120` | Mada, Mastercard co-brand |
To test Mada through Apple Pay, you need:
- A device compatible with Apple Pay
- A sandbox Apple Pay wallet, which you have added a Mada test card to – For more information, see the Apple Pay [Sandbox testing](https://developer.apple.com/apple-pay/sandbox-testing/) documentation
To check the status of a payment:
1. Sign in to the [Dashboard](https://dashboard.checkout.com/).
2. Go to _Payments_ > _Processing_ > _All payments_.
3. Select the test payment to view its details.
---
## Next steps
**[Customize your Flow integration](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/customize-your-flow-integration.md)**
Learn how to customize your Flow integration.
**[Flow library reference](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/flow-library-reference.md)**
See the configuration options and error handling steps for Flow.