# Payment lifecycle

This page describes the payment lifecycle and how to make a basic in-person payment request. An
in-store payment transaction moves through four stages: the POS creates a pay request, the customer
authorises it on the terminal, a receipt is optionally printed, and — if needed later — the POS can
refund the payment back to the original payment method.

Create pay request
The POS operator creates a pay request for a certain amount that is linked to an order in the POS
system. Only the total amount and a reference to the order are added to the pay request — the POS
doesn't need to send order line items, only the `total` amount and the order's reference in
`origin.orderId`.

Call [Create a Pay Request](/api-explorer/pay-in-person/0.9/pay-requests/create-pay-terminal-request)
with the `mid`, `tid`, `total`, and `origin` object. Inside `origin`, only `orderId` (the reference
generated by the POS for reconciliation) and `transactionId` are required — no other order detail is
sent to the terminal.

`goodsAndServicesAmount`, `cashoutAmount`, and `refundAmount` are all integers in cents, e.g. `12520` for $125.20. Keep the amount as an integer throughout your POS —
never round it or store it as a float — to avoid floating-point precision errors carrying through to
the terminal.

Authorise on terminal
The customer uses their debit or credit card to pay on the terminal and enters their PIN if requested
by their issuer.

During this step, the POS can:

- Send a [Cancel a Pay Request](/api-explorer/pay-in-person/0.9/pay-requests/cancel-pay-terminal-request) to cancel the transaction.
- Call [Retrieve a Pay Request](/api-explorer/pay-in-person/0.9/pay-requests/get-pay-terminal-request) to poll the current status, or subscribe to [notification events](/api-explorer/pay-in-person/0.9/notification-events) for real-time authorisation updates.


Print receipt
The terminal, or hardware provided by the POS, will optionally print a receipt for the customer.

Receipt content must be printed or stored in the POS journal without modification, and a customer
copy must be made available for every outcome — approved, declined, cancelled, or reversed. The full
merchant-copy and customer-copy requirements are covered by
[Integrated receipts](/docs/in-person-payments/pay-in-person/features/integrated-receipts).

Refund pay request
The POS operator can decide to refund the payment to the same payment method as the original
transaction.

The [Refunds API](/docs/business-operations/refunds/overview) is available for refunds after the
customer has left the store. This can be used by your admin and finance staff.

## Payment states

For every integration method a transaction moves between four states; created, in progress, approve, and not approved. At each transition the transaction is passed between the POS, terminal, or card issuer. The field and event names differ per integration method.


```mermaid
stateDiagram-v2
    direction TB
    state "Created" as Created
    state "In progress" as InProgress
    state "Approved" as Approved
    state "Not approved" as NotApproved

    [*] --> Created: POS starts
    Created --> InProgress: Terminal picks up
    Created --> NotApproved: Terminal offline
    InProgress --> Approved: Issuer approves
    InProgress --> NotApproved: Declined, error or cancelled
    Approved --> [*]
    NotApproved --> [*]
```

| State | Triggered by | What happens |
|  --- | --- | --- |
| Created | **POS** | The POS starts a purchase, refund, or cashout. The request exists but the terminal hasn't picked it up yet. |
| In progress | **Terminal**, then **POS** | The terminal runs the cardholder through tap/insert/swipe and PIN entry, reporting status messages as it goes. It may also ask the POS a question it needs answered to continue (for example, a signature confirmation or "print receipt?") — the POS answers, and the terminal resumes. |
| Approved | **Issuer** | The card issuer authorised the transaction and money moves. This is the only state where funds are actually debited or credited. |
| Not approved | **Issuer**, **Terminal**, or **POS** | The issuer declined the card, the terminal or network hit an error, or the transaction was cancelled (by the customer, merchant, or POS) before it reached an outcome. Nothing has moved financially. |


## Example: create a payment

A minimal example of step 1 (create pay request) in each integration method. Each snippet is
self-contained — see its linked reference page for the full request/response and event handling.

JS library

```javascript
var amount = '1000';

function doPurchase(amount) {
    iclient.initiatePurchase({
        amount: amount,
        enableSurcharge: true,
        integratedReceipt: false
    }, {
        receiptCallback: receiptCallbackImpl,
        transactionCompleteCallback: transactionCompleteCallbackImpl
    });
}
```

The full callback reference is covered by
[Payment, cashout and refund](/docs/in-person-payments/pay-in-person/features/payment-cashout-refund).

.NET library

```csharp
bool started = terminalAdapter.PurchaseAdditionalData(
    amountInCents: 1000,
    cashoutInCents: 0,
    "{ 'enableSurcharge': true }"
);

terminalAdapter.TransactionCompleted += (sender, e) =>
{
    if (e.GetResult() == "APPROVED")
    {
        // Money has moved — reconcile using e.GetID() and e.GetTransactionReference().
    }
};
```

The full method and event reference is covered by
[Payment, cashout and refund](/docs/in-person-payments/pay-in-person/features/payment-cashout-refund).

Android SDK

```kotlin
val parameters = mutableMapOf<String, Any>(
    "mid" to "123",
    "tid" to "456",
    "amount" to 1000
)

tyroClient.performOperation(
    "purchase",
    parameters,
    { receipt -> },
    { data ->
        if (data["status"] == "success") {
            // Money has moved — reconcile using data["transactionId"].
        }
    }
)
```

In-store API
Call [Create a Pay Request](/api-explorer/pay-in-person/0.9/pay-requests/create-pay-terminal-request):


```json
{
  "mid": "123",
  "tid": "456",
  "origin": {
    "orderId": "2e6174ae-ba4f-4a02-8072-9304d862e320",
    "transactionId": "2e6174ae-ba4f-4a02-8072-9304d862e320"
  },
  "total": {
    "goodsAndServicesAmount": 1000,
    "cashoutAmount": 0,
    "refundAmount": 0,
    "currency": "AUD"
  }
}
```

Tracking and rate-limit details are covered by
[Payment, cashout and refund](/docs/in-person-payments/pay-in-person/features/payment-cashout-refund).