# Payments
URL: /docs/a2a/payments

Start payments, cancel payments, EFT-POS payments and order payments.

This page covers the single-transaction payment operations. They all return a
[`PPStartPaymentResponseModel`](/docs/a2a/reference#ppstartpaymentresponsemodel)
(except order payment, which returns
[`PPOrderPaymentResponseModel`](/docs/a2a/reference#pporderpaymentresponsemodel)).

Each request is created with a `toRequest(...)` factory. Flutter and React
Native use `camelCase` parameter names; the native Android package uses
`snake_case`.

## Start a payment

Starts a new payment on POS+ for an order.

<Callout type="warn">
  The order must first be created via the API. The `orderCode` you pass must
  belong to that order; otherwise an **order not found** error is returned.
</Callout>

### Parameters

| Parameter            | Type                                                               | Required | Description                       |
| -------------------- | ------------------------------------------------------------------ | -------- | --------------------------------- |
| `orderCode`          | String                                                             | yes      | Your unique order code            |
| `paymentType`        | [`PPPaymentType`](/docs/a2a/reference#pppaymenttype)               | yes      | e.g. `POS`, `CASH`                |
| `paymentMethod`      | [`PPPaymentMethod`](/docs/a2a/reference#pppaymentmethod)           | yes      | e.g. `CC`, `QR`, `NFC`            |
| `totalAmount`        | double                                                             | yes      | Total amount to charge            |
| `installment`        | int                                                                | no       | Number of installments            |
| `isPartial`          | bool                                                               | no       | Partial payment (default `false`) |
| `partialType`        | [`PPPartialPaymentType`](/docs/a2a/reference#pppartialpaymenttype) | no       | `AMOUNT` or `PRODUCT`             |
| `products`           | List\<PPProduct>                                                   | no       | Line items (`id`, `qty`)          |
| `billingInformation` | PPBillingInfo                                                      | no       | Invoice / billing details         |

<CodeBlockTabs defaultValue="flutter" groupId="pp-platform" persist>
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="flutter">
      Flutter
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="kotlin">
      Kotlin
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="java">
      Java
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="react-native">
      React Native
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="flutter">
    ```dart
    final result = await _pluspay.startPayment(
      PPStartPaymentRequestModel.toRequest(
        orderCode: 'ORD001',
        totalAmount: 11.9,
        paymentType: PPPaymentType.POS,
        paymentMethod: PPPaymentMethod.CC,
      ),
    );

    print(result.status);     // transaction status
    print(result.id);         // POS+ transaction id
    print(result.payment?.rrn); // bank reference number
    ```
  </CodeBlockTab>

  <CodeBlockTab value="kotlin">
    ```kotlin
    val request = PPStartPaymentRequestModel.toRequest(
        order_code = "ORD001",
        total_amount = 11.9,
        payment_type = PPPaymentType.POS,
        payment_method = PPPaymentMethod.CC,
    )

    // Coroutine style
    val result = client.startPayment(request)

    // or callback style
    client.startPayment(request, object : PPA2ACallback<PPStartPaymentResponseModel> {
        override fun onSuccess(result: PPStartPaymentResponseModel) {
            // handle success
        }
        override fun onError(e: PlusPayException) {
            // handle error
        }
    })
    ```
  </CodeBlockTab>

  <CodeBlockTab value="java">
    ```java
    String request = PPStartPaymentRequestModel.toRequest(
        "ORD001",              // order_code
        11.9,                  // total_amount
        PPPaymentType.POS,     // payment_type
        PPPaymentMethod.CC     // payment_method
    );

    client.startPayment(request, new PPA2ACallback<PPStartPaymentResponseModel>() {
        @Override
        public void onSuccess(PPStartPaymentResponseModel result) {
            // handle success
        }
        @Override
        public void onError(PlusPayException e) {
            // handle error
        }
    });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="react-native">
    ```ts
    const result = await client.startPayment(
      PPStartPaymentRequestModel.toRequest({
        orderCode: 'ORD001',
        totalAmount: 11.9,
        paymentType: PPPaymentType.POS,
        paymentMethod: PPPaymentMethod.CC,
      })
    );

    console.log(result.status); // transaction status
    console.log(result.id);     // POS+ transaction id
    console.log(result.rrn);    // bank reference number
    ```
  </CodeBlockTab>
</CodeBlockTabs>

<Callout>
  For a partial payment set `isPartial: true` and provide `partialType`
  (`AMOUNT` or `PRODUCT`). For product-based partial payments also pass
  `products`.
</Callout>

## Cancel a payment

Cancels a previously completed payment by its transaction id.

### Parameters

| Parameter       | Type   | Required | Description                         |
| --------------- | ------ | -------- | ----------------------------------- |
| `transactionId` | String | yes      | Id returned by the original payment |
| `orderCode`     | String | yes      | The original order code             |
| `note`          | String | no       | Free-text cancellation note         |

<CodeBlockTabs defaultValue="flutter" groupId="pp-platform" persist>
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="flutter">
      Flutter
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="kotlin">
      Kotlin
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="java">
      Java
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="react-native">
      React Native
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="flutter">
    ```dart
    await _pluspay.cancelPayment(
      PPCancelPaymentRequestModel.toRequest(
        orderCode: 'ORD001',
        transactionId: '539c5225-0741-4f0e-b460-1fdb842c2c16',
        note: 'Customer cancelled',
      ),
    );
    ```
  </CodeBlockTab>

  <CodeBlockTab value="kotlin">
    ```kotlin
    val request = PPCancelPaymentRequestModel.toRequest(
        order_code = "ORD001",
        transaction_id = "539c5225-0741-4f0e-b460-1fdb842c2c16",
        note = "Customer cancelled",
    )

    val result = client.cancelPayment(request)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="java">
    ```java
    String request = PPCancelPaymentRequestModel.toRequest(
        "ORD001",
        "539c5225-0741-4f0e-b460-1fdb842c2c16",
        "Customer cancelled"
    );

    client.cancelPayment(request, new PPA2ACallback<PPStartPaymentResponseModel>() {
        @Override public void onSuccess(PPStartPaymentResponseModel r) {}
        @Override public void onError(PlusPayException e) {}
    });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="react-native">
    ```ts
    await client.cancelPayment(
      PPCancelPaymentRequestModel.toRequest({
        orderCode: 'ORD001',
        transactionId: '539c5225-0741-4f0e-b460-1fdb842c2c16',
        note: 'Customer cancelled',
      })
    );
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## EFT-POS payment

Starts a payment directly on the EFT-POS device. Requires a tax rate.

### Parameters

| Parameter       | Type                                                     | Required | Description            |
| --------------- | -------------------------------------------------------- | -------- | ---------------------- |
| `totalAmount`   | double                                                   | yes      | Amount to charge       |
| `paymentType`   | [`PPPaymentType`](/docs/a2a/reference#pppaymenttype)     | yes      | Payment type           |
| `paymentMethod` | [`PPPaymentMethod`](/docs/a2a/reference#pppaymentmethod) | yes      | Payment method         |
| `transactionId` | String                                                   | yes      | Your transaction id    |
| `taxRate`       | int                                                      | yes      | Applied tax rate (%)   |
| `installment`   | int                                                      | no       | Number of installments |

<CodeBlockTabs defaultValue="flutter" groupId="pp-platform" persist>
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="flutter">
      Flutter
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="kotlin">
      Kotlin
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="java">
      Java
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="react-native">
      React Native
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="flutter">
    ```dart
    await _pluspay.startEftPayment(
      PPEftPaymentRequestModel.toRequest(
        totalAmount: 3.0,
        paymentType: PPPaymentType.POS,
        paymentMethod: PPPaymentMethod.CC,
        transactionId: '27517a85-cfc3-4eee-b83b-63dc6bcb9fd6',
        taxRate: 0,
      ),
    );
    ```
  </CodeBlockTab>

  <CodeBlockTab value="kotlin">
    ```kotlin
    val request = PPEftPaymentRequestModel.toRequest(
        total_amount = 3.0,
        payment_type = PPPaymentType.POS,
        payment_method = PPPaymentMethod.CC,
        transaction_id = "27517a85-cfc3-4eee-b83b-63dc6bcb9fd6",
        tax_rate = 0,
    )

    val result = client.startEftPayment(request)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="java">
    ```java
    String request = PPEftPaymentRequestModel.toRequest(
        3.0,
        PPPaymentType.POS,
        PPPaymentMethod.CC,
        "27517a85-cfc3-4eee-b83b-63dc6bcb9fd6",
        0          // tax_rate
    );

    client.startEftPayment(request, new PPA2ACallback<PPStartPaymentResponseModel>() {
        @Override public void onSuccess(PPStartPaymentResponseModel r) {}
        @Override public void onError(PlusPayException e) {}
    });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="react-native">
    ```ts
    await client.startEftPayment(
      PPEftPaymentRequestModel.toRequest({
        totalAmount: 3.0,
        paymentType: PPPaymentType.POS,
        paymentMethod: PPPaymentMethod.CC,
        transactionId: '27517a85-cfc3-4eee-b83b-63dc6bcb9fd6',
        taxRate: 0,
      })
    );
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Cancel an EFT-POS payment

### Parameters

| Parameter       | Type   | Required | Description                   |
| --------------- | ------ | -------- | ----------------------------- |
| `transactionId` | String | yes      | The EFT transaction id        |
| `totalAmount`   | double | yes      | Amount of the EFT transaction |

<CodeBlockTabs defaultValue="flutter" groupId="pp-platform" persist>
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="flutter">
      Flutter
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="kotlin">
      Kotlin
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="java">
      Java
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="react-native">
      React Native
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="flutter">
    ```dart
    await _pluspay.cancelEftPayment(
      PPEftCancelRequestModel.toRequest(
        transactionId: 'a111ed26-ed2b-4f0b-9d6c-82056e52c96c',
        totalAmount: 3.0,
      ),
    );
    ```
  </CodeBlockTab>

  <CodeBlockTab value="kotlin">
    ```kotlin
    val request = PPEftCancelRequestModel.toRequest(
        transaction_id = "a111ed26-ed2b-4f0b-9d6c-82056e52c96c",
        total_amount = 3.0,
    )

    val result = client.cancelEftPayment(request)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="java">
    ```java
    String request = PPEftCancelRequestModel.toRequest(
        "a111ed26-ed2b-4f0b-9d6c-82056e52c96c",
        3.0
    );

    client.cancelEftPayment(request, new PPA2ACallback<PPStartPaymentResponseModel>() {
        @Override public void onSuccess(PPStartPaymentResponseModel r) {}
        @Override public void onError(PlusPayException e) {}
    });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="react-native">
    ```ts
    await client.cancelEftPayment(
      PPEftCancelRequestModel.toRequest({
        transactionId: 'a111ed26-ed2b-4f0b-9d6c-82056e52c96c',
        totalAmount: 3.0,
      })
    );
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Pay an existing order

Pays an order that already exists in POS+, addressed only by its order code.
Returns a [`PPOrderPaymentResponseModel`](/docs/a2a/reference#pporderpaymentresponsemodel)
containing the order totals and the list of transaction results.

### Parameters

| Parameter   | Type   | Required | Description                     |
| ----------- | ------ | -------- | ------------------------------- |
| `orderCode` | String | yes      | The existing order code in POS+ |

<CodeBlockTabs defaultValue="flutter" groupId="pp-platform" persist>
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="flutter">
      Flutter
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="kotlin">
      Kotlin
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="java">
      Java
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="react-native">
      React Native
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="flutter">
    ```dart
    final result = await _pluspay.startOrderPayment(
      PPOrderPaymentRequestModel.toRequest(
        orderCode: 'ORD001',
      ),
    );

    print(result.status);     // PPOrderStatusEnum
    print(result.amountDue);
    for (final r in result.results) {
      print('${r.completed} ${r.errorMessage}');
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="kotlin">
    ```kotlin
    val request = PPOrderPaymentRequestModel.toRequest(
        order_code = "ORD001",
    )

    val result = client.startOrderPayment(request)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="java">
    ```java
    String request = PPOrderPaymentRequestModel.toRequest(
        "ORD001"
    );

    client.startOrderPayment(request, new PPA2ACallback<PPOrderPaymentResponseModel>() {
        @Override public void onSuccess(PPOrderPaymentResponseModel r) {}
        @Override public void onError(PlusPayException e) {}
    });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="react-native">
    ```ts
    const result = await client.startOrderPayment(
      PPOrderPaymentRequestModel.toRequest({ orderCode: 'ORD001' })
    );

    console.log(result.status);      // order status
    console.log(result.amount_due);
    result.results?.forEach((r) => console.log(r.completed, r.error_message));
    ```
  </CodeBlockTab>
</CodeBlockTabs>

Next: [Multi-payment](/docs/a2a/multi-payment) for product-based orders with
multiple transactions.