# Request to Pay (POS)

Push a payment request straight to a registered shopper’s PayLater app by mobile number — ideal for in-store / point of sale. The shopper approves and pays in-app.

**POST** `/api/paylater/merchant-portal/v2/web-checkout/request-to-pay`

- Sandbox: `https://connect.uat.paylaterapp.com/api/paylater/merchant-portal/v2/web-checkout/request-to-pay`
- Production: `https://connect.paylaterapp.com/api/paylater/merchant-portal/v2/web-checkout/request-to-pay`

> **Info: Authentication**
>
> Requires a bearer token from the [OAuth 2.0 token endpoint](https://docs.paylaterapp.com/authentication.html). Pass it as `Authorization: Bearer <ACCESS_TOKEN>`.

## Request

#### Headers

| Header | Value |
| --- | --- |
| `Authorization` | `Bearer <ACCESS_TOKEN>` |
| `Content-Type` | `application/json` |

**Body parameters**

- `outlet_id` (Number, required): Storefront / outlet identifier.
- `mobile_number` (String, required): Registered customer mobile number.
- `order_amount` (Decimal, required): Requested payment amount.
- `merchant_order_reference` (String, required): Your unique transaction reference.
- `expiry_minutes` (Integer, required): Expiry time in minutes.

### Example request

**cURL**

```bash
curl --location 'https://connect.uat.paylaterapp.com/api/paylater/merchant-portal/v2/web-checkout/request-to-pay' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{ "outlet_id": 1000000061, "mobile_number": "97451118021", "order_amount": 3015, "merchant_order_reference": "ORD-5", "expiry_minutes": 20 }'
```

**Node.js**

```javascript
const res = await fetch(
  'https://connect.uat.paylaterapp.com/api/paylater/merchant-portal/v2/web-checkout/request-to-pay',
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      outlet_id: 1000000061,
      mobile_number: '97451118021',
      order_amount: 3015,
      merchant_order_reference: 'ORD-5',
      expiry_minutes: 20,
    }),
  },
);

const data = await res.json();
```

**Python**

```python
import requests

resp = requests.post(
    "https://connect.uat.paylaterapp.com/api/paylater/merchant-portal/v2/web-checkout/request-to-pay",
    headers={
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json",
    },
    json={
        "outlet_id": 1000000061,
        "mobile_number": "97451118021",
        "order_amount": 3015,
        "merchant_order_reference": "ORD-5",
        "expiry_minutes": 20,
    },
)

data = resp.json()
```

**PHP**

```php
$ch = curl_init('https://connect.uat.paylaterapp.com/api/paylater/merchant-portal/v2/web-checkout/request-to-pay');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $accessToken,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'outlet_id' => 1000000061,
        'mobile_number' => '97451118021',
        'order_amount' => 3015,
        'merchant_order_reference' => 'ORD-5',
        'expiry_minutes' => 20,
    ]),
]);

$response = json_decode(curl_exec($ch), true);
```

## Response

A `200 OK` confirms the request was pushed to the shopper’s PayLater app.

**200 OK**

```json
{
  "merchant_order_reference": "ORD-5",
  "status": "SUCCESS",
  "expiry_date": "2026-04-28T10:15:41.477013291"
}
```

## Errors

A duplicate `merchant_order_reference` returns `409`:

```json
{
  "status": "FAILED",
  "message": "A Request-to-Pay already exists for this merchant order reference.",
  "http_code": 409,
  "error_reference": "RTP-409-DUPLICATE-REFERENCE"
}
```

An upstream failure returns `404`:

```json
{
  "status": "FAILED",
  "message": "Unable to process Request-to-Pay right now. Please try again later.",
  "http_code": 404,
  "error_reference": "RTP-UPSTREAM-ERROR"
}
```

See [Error handling & response codes](https://docs.paylaterapp.com/errors.html) for the full catalogue.
