> ## Documentation Index
> Fetch the complete documentation index at: https://developer.novacpayment.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Checkout

> Learn how to complete payments with custom checkouts.

## Overview

You may want your customers to complete a payment via a custom checkout tailored to your brand aesthitics and user experience. Custom checkout with Novac exposes the API that power our prebuilt checkout to merchant looking at creating an experience of thier own while we still handle the payment processing behind the scene.

You only control the payment completion logic while we handle the payment processing.

***

## Prerequisite

<Accordion title="See details">
  Before completing a payment via the prebuilt checkout, ensure that you have:

  * Created a checkout payment with a [transaction reference](/docs/accept-payment/checkout/create-checkout-with-transaction-reference) or [payment link reference](/docs/accept-payment/accept-payment-with-payment-links#create-a-checkout-payment-with-payment-link-reference), this provides the `paymentRedirectUrl` needed for redirection.
  * Set up your `redirectUrl` either on the dashboard or in the API request to ensure users are properly redirected after payment completion.
</Accordion>

***

## Custom Checkout Flows

After successfully creating a checkout payment, you can use the `transactionReference` return as part of the response object to start a custom checkout process. this requires that you have built a form in your frontend that shows the amount charged. We exposes an API that also allow you to fetch transaction fees, complete payment with card, ussd or bank transfer.

After creating a checkout payment, you’ll receive a response that includes a `paymentRedirectUrl` field:

```json expandable created checkout payment response data theme={null}
{
    "status": true,
    "message": "Transaction Initialized successfully",
    "data": {
        "transactionReference": "1oWbJQQHLyQqqf1SwxjSpudeA01nm",
        "amount": 1000,
        "statusCode": "01",
        "statusMessage": "Transaction initiated successfully",
        "publicKey": "nc_testpk_a0kuivx6lst100haeqo2eyoxkcqdmmeyyr",
        "paymentRedirectUrl": "https://www.app.novacpayment.com/pay/payments?reference=1oWbJQQHLyQqqf1SwxjSpudeA01nm",
        "collectionPaymentOptions": "CARD,PWBT,USSD,NQR"
    }
}
```

Lets build a simple payment completion logic using Javascript as our frontend, we will build a simple form using HTML, JS

***

### Redirect Customers to your Custom Payment UI

On your custom checkout page, you will complete the payment with the `transactionReference` from the created checkout payment. Your customers have the option to use either USSD, card, Opay, Palmpay or transfer. Depending on what they select, you will call any of the APIs below to complete the payment.

<CodeGroup>
  ```bash Card Payment theme={null}
  curl --request POST \
    --url https://api.novacpayment.com/api/v1/card-payment \
    --header 'Authorization: <api-key>' \
    --header 'Content-Type: application/json' \
    --data '{
    "cardNumber": "<string>",
    "expiryMonth": "<string>",
    "expiryYear": "<string>",
    "cvv": "<string>",
    "cardPin": "<string>",
    "transactionReference": "<string>"
  }'

  ```

  ```bash Transfer Payment theme={null}
  curl --request POST \
    --url https://api.novacpayment.com/api/v1/bank-transfer \
    --header 'Authorization: <api-key>' \
    --header 'Content-Type: application/json' \
    --data '{
    "transactionReference": "<string>",
    "paymentType": "<string>",
    "cardBin": "<string>"
  }'

  ```

  ```bash USSD payment theme={null}
  curl --request POST \
    --url https://api.novacpayment.com/api/v1/ussd-payment \
    --header 'Authorization: <api-key>' \
    --header 'Content-Type: application/json' \
    --data '{
    "transactionReference": "<string>",
    "bankCode": "<string>"
  }'

  ```
</CodeGroup>

#### Opay integration

To complete payment with OPay integration, make a `POST` request and pass the transaction ref used when creating the checkout payment.
Pass it as a query parameter.

Redirect the customer to the `cashierUrl` page to complete the payment.

```bash Opay request theme={null}
curl --request POST \
  --url  https://api.novacpayment.com/api/v1/opay-payment?transactionReference={tranref} \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
```

```bash Opay response theme={null}
{
    "status": true,
    "message": "Opay transaction initiated.",
    "data": {
        "cashierUrl": "https://express.opaycheckout.com/apiCashier/redirect/payment/checkoutHome?orderToken=TOKEN.7a99a4845931441b8607f32a255693eb",
        "reference": "NCPL20260610084349652371AFXR4P",
        "orderNo": "260610145662165989858",
        "status": "INITIAL",
        "amount": {
            "total": 30000,
            "currency": "NGN"
        },
        "vat": {
            "total": 0,
            "currency": "NGN"
        }
    }
}
```

#### Palmpay integration

Make a `POST` request to this endpoint, ensure you pass the  unique reference used during checkout creation. When the request is successful redirect customer to `checkoutUrl` to complete the payment.

```bash Palmpay request theme={null}
curl --request POST \
  --url https://api.novacpayment.com/api/v1/palmpay-payment?transactionReference={tranref} \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
```

```bash Palmpay response theme={null}
{
    "status": true,
    "message": "Palmpay transaction initiated.",
    "data": {
        "checkoutUrl": "https://checkout.palmpay.com/h5-checkout/?countryCode=NG&tntCode=PALMPAY&payToken=CA3FE89AA866FF827B66FBCABC3E05E1&orderNo=24260610084630346817&signKey=HAcl9Y-MSLtefSXGqOahZsTK1B5kfVeP7BnkneewFeg&signSession=24260610084630346817&appId=L250813121766924290401&productType=pay_wallet&businessProductType=pay_wallet&businessMode=three_mode&identityType=NEW&callable=%7B%22android%22%3A%22true%22%2C%22ios%22%3A%22true%22%7D",
        "currency": "NGN",
        "message": "",
        "orderAmount": 30000,
        "orderNo": "24260610084630346817",
        "orderStatus": 0,
        "payToken": "CA3FE89AA866FF827B66FBCABC3E05E1",
        "sdkSessionId": "24260610084630346817",
        "sdkSignKey": "HAcl9Y-MSLtefSXGqOahZsTK1B5kfVeP7BnkneewFeg"
    }
}
```

You can explore more about the API that powers our checkout page below

* [Complete card payments](/api-reference/custom-checkout/complete-card-payment)
* [Complete bank transfer payment](/api-reference/custom-checkout/complete-bank-transfer)
* [Complete USSD payments](/api-reference/custom-checkout/complete-ussd-payment)
* [See List of supported USSD banks](/api-reference/custom-checkout/get-bank-ussd)

***

## MoMo Custom Checkout Flow

To build a custom MoMo checkout experience, you must first create a payment intent by
initiating a [MoMo checkout payment](/docs/accept-payment/checkout/create-checkout-for-mobile-money-payment).
Use the `reference` returned from that step throughout this flow.

### Get Supported MoMo Providers

Before collecting the customer's mobile money details, fetch the list of supported providers to populate your UI and retrieve the correct `bank_code` for the next step.

```bash theme={null}
curl --request GET \
  --url https://integrations.novacpayment.com/api/v1/mobilemoneybanks/GHS \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json'
```

```json Response theme={null}
{
  "success": true,
  "message": "Bank list retrieved",
  "currency": "GHS",
  "data": [
    {
      "bank_name": "MTN Ghana",
      "bank_code": "MTNGH"
    },
    {
      "bank_name": "Telecel Ghana",
      "bank_code": "TCELGH"
    }
  ]
}
```

<Note>
  Two MoMo providers are currently supported — MTN Ghana and Telecel Ghana. This list will be updated as additional providers are added.
</Note>

***

### Create the MoMo Payment

Once the account is validated, submit the payment request using the `reference` from your checkout, along with the customer's account details. Novac will trigger a payment approval prompt on the customer's mobile money app.

```bash theme={null}
curl --request POST \
  --url https://api.novacpayment.com/api/v1/momo-payment \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "reference": "{reference}",
    "accountNumber": "{account_number}",
    "bankCode": "{bank_code}"
  }'
```

```json Response theme={null}
{
  "status": true,
  "message": "Momo transaction initiated."
}
```

<Info>
  A successful response confirms the request was received. The transaction is not yet
  complete at this point, the customer must approve the payment prompt on their mobile
  money app to settle the transaction. Once approved, Novac will notify you of the
  payment status via webhooks.
</Info>

## What’s Next?

Learn how to verify transactions after payment is completed:

* Using Webhooks: Automatically receive payment status updates from Novac when a transaction is completed.\
  [Learn how to verify a transaction via webhooks](/docs/api-basics/webhooks)

* Using the Callback URL: Manually verify the payment using the `reference` parameter sent to your callback URL.\
  [Learn how to verify a transaction using a callback reference](/docs/accept-payment/manage-payment/verify-transaction)
