# Shukria Payments — How a Payment Works

A reference for deciding how your order system should behave. It covers what happens at
each step, what your system receives, and how to reconcile.

For the code, see [INTEGRATION.md](INTEGRATION.md).

---

## Contents

- [The short version](#the-short-version)
- [The full flow](#the-full-flow)
- [Card security](#card-security)
- [Payment states](#payment-states)
- [When the payer does not come back](#when-the-payer-does-not-come-back)
- [Additional authentication](#additional-authentication-3-d-secure)
- [Reconciliation](#reconciliation)
- [What is under your control](#what-is-under-your-control)

---

## The short version

```mermaid
flowchart LR
  A["Your checkout page"] -->|"one JavaScript call"| B["Shukria Payments"]
  B -->|"secure payment window"| C["Customer enters card"]
  C -->|"authorisation request"| D["Card network<br/>and issuing bank"]
  D -->|"approved or declined"| B
  B -->|"result envelope"| A

  classDef you fill:#EEF1F3,stroke:#5C6B72,stroke-width:1.5px,color:#101820;
  classDef shukria fill:#E2EFF0,stroke:#0E7C86,stroke-width:1.5px,color:#101820;
  classDef bank fill:#F6EBDA,stroke:#A8690D,stroke-width:1.5px,color:#101820;

  class A,C you;
  class B shukria;
  class D bank;
```

Your site talks to Shukria. Shukria talks to the payment networks. You receive one
consistent result whichever network settles the payment.

---

## The full flow

```mermaid
sequenceDiagram
  autonumber
  participant C as Customer
  participant M as Your site
  participant S as Shukria Payments
  participant B as Card network / bank

  M->>S: Start payment (amount, orderId, customer)
  S-->>M: Secure payment window opens
  C->>S: Enters card details
  Note over C,S: Card details go straight to the<br/>secure payment page. They never<br/>pass through your servers.
  S->>B: Authorisation request
  B-->>S: Approved or declined
  S->>S: Record the outcome
  S-->>M: Result envelope (status_code)
  S-->>M: Redirect to your returnUrl
  M->>S: Verify status from your server
  S-->>M: Confirmed status
  M->>C: Order confirmed
```

Steps 10 and 11 are the important ones: **confirm from your server before fulfilling.**
Everything before that reaches you through the customer's browser.

---

## Card security

Card details are entered on a secure payment page and sent directly to the payment
provider. They do not pass through your website or servers at any point.

You receive only:

- the **last four digits**, as `masked_card`
- an **approval code**, when the payment is approved
- a **transaction reference**

You never receive, and should never store, a full card number, expiry date, or CVV.

> [!NOTE]
> This is what keeps card-security obligations off your systems. If any integration ever
> appears to send you a full card number, stop and contact Shukria — that is not how the
> integration is designed to work.

---

## Payment states

```mermaid
stateDiagram-v2
  [*] --> Pending: payment started
  Pending --> Success: approved
  Pending --> Failed: declined or cancelled
  Pending --> Pending: awaiting bank confirmation
  Success --> [*]
  Failed --> [*]

  note right of Pending
    status_code 1100
    Do NOT fulfil.
    Do NOT mark failed.
  end note

  note right of Success
    status_code 1200
    Verify, then fulfil.
  end note

  note right of Failed
    status_code 1400
    Retry needs a NEW orderId.
  end note
```

| State | Code | Money taken? | Your action |
|---|---|---|---|
| **Success** | `1200` | Yes | Verify on your server, then fulfil |
| **Failed** | `1400` | No | Invite a retry with a new `orderId` |
| **Pending** | `1100` | Undetermined | Hold. Re-check shortly |

A payment never moves back out of Success or Failed. Pending is the only state that
changes on its own.

---

## When the payer does not come back

Customers close tabs, lose signal, and get interrupted. This is common enough to design
for rather than treat as an edge case.

```mermaid
flowchart TB
  A["Customer starts paying"] --> B{"Did your callback<br/>or returnUrl fire?"}
  B -->|"yes"| C["Verify status from your server"]
  B -->|"no"| D["Query the status endpoint<br/>with your orderId"]
  C --> E{"status_code?"}
  D --> E
  E -->|"1200"| F["Fulfil the order"]
  E -->|"1400"| G["Failed — offer a retry"]
  E -->|"1100"| H["Hold; re-check shortly"]
  H --> D

  classDef you fill:#EEF1F3,stroke:#5C6B72,stroke-width:1.5px,color:#101820;
  classDef check fill:#FFFFFF,stroke:#8A6D1F,stroke-width:1.5px,color:#101820;
  classDef good fill:#E3F2E9,stroke:#1B7A4B,stroke-width:1.5px,color:#101820;
  classDef bad fill:#F7E4E1,stroke:#A82A1E,stroke-width:1.5px,color:#101820;

  class A,C,D you;
  class B,E check;
  class F good;
  class G bad;
  class H you;
```

The payment is recorded on Shukria's side the moment it is approved, whether or not the
customer's browser returns. Querying by your own `orderId` will always find it.

---

## Additional authentication (3-D Secure)

Some cards require the customer to confirm with their bank — a one-time code, a banking
app approval, or similar. When that happens the customer is briefly shown their **bank's**
page before returning.

Your integration needs no changes for this. It affects only how long a payment takes, so:

- Do not time out a payment aggressively
- Expect some payments to take a minute or more
- Do not assume an unreturned payment failed

If the customer fails or abandons that step, the payment comes back as `1400` and **the
card is not charged**.

---

## Reconciliation

To confirm a day's payments, query each order:

```bash
curl -s "https://shukriapg.ariticapp.com/pgpayments/pay/status/ORD_1755512400000"
```

Match on:

| Field | Against |
|---|---|
| `order_id` | Your order reference |
| `amount` | Your order total |
| `status_code` | `1200` for settled payments |
| `transaction_id` | Your record of the payment reference |

Any order your system shows as paid but which returns `1400` or `404` needs investigating.
An order showing `1100` has not finished — re-check before treating it as either.

---

## What is under your control

| | Yours | Shukria's |
|---|---|---|
| Order reference (`orderId`) | ✅ | |
| Amount and currency | ✅ | |
| Customer details sent | ✅ | |
| Deciding when to fulfil | ✅ | |
| Card data handling | | ✅ |
| Which payment network is used | | ✅ |
| Authorisation and settlement | | ✅ |
| Payment record and status | | ✅ |

Which network settles a payment is managed by Shukria and may change. Because the result
envelope and the status endpoint are the same either way, such a change requires nothing
from you.

---

Questions: contact Shukria with your `merchantId`, the `orderId`, and the
`transaction_id`. See [INTEGRATION.md](INTEGRATION.md#support).
