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

# Wallets

> This page describes how merchants integrate digital Wallets as a payment option via Monxa

## Overview

A digital **Wallet** (e-wallet) allows users to store value or link funding sources and authorize payments using the stored wallet or linked instruments. In many markets, digital wallets are a preferred method due to convenience, familiarity, and strong authentication.

By offering digital wallet payments via Monxa, merchants can:

* Provide a frictionless checkout experience
* Tap into local wallet popularity in Asia
* Leverage Monxa’s settlement, reconciliation, and refund capabilities in one unified system

<Columns cols={2}>
  <Card title="1. Create a Charge" icon="star" iconType="solid" href="#">
    Initiate the payment by creating a **charge** in your system with the transaction details.
  </Card>

  <Card title="2. Redirect Customer to e-Wallet" icon="diamond-turn-right" iconType="solid" href="#">
    Use the `return_url` from Monxa to send the customer to their e-wallet app or hosted page.
  </Card>

  <Card title="3. Customer Authorizes Payment" icon="mobile-screen-button" iconType="solid" href="#">
    The customer confirms the transaction by entering their **PIN/OTP** or using biometric authentication in their e-wallet.
  </Card>

  <Card title="4. Handle Webhooks" icon="anchor" iconType="solid" href="#">
    Once the e-wallet provider processes the payment, Monxa sends a **webhook notification** to update your system with the final status.
  </Card>
</Columns>

## Supported Channels

<Tabs>
  <Tab title="🇮🇩 Indonesia">
    | Channel                               | Code             | **Currency** | **Refund**    | **Settlement** | Min Amount | Max  Amount |
    | :------------------------------------ | ---------------- | :----------- | :------------ | :------------- | ---------- | :---------- |
    | [DANA](https://www.dana.id/)          | `wallet_dana`    | IDR          | Full, Partial | T+2            | 100        | 20,000,000  |
    | [OVO](https://www.ovo.id/)            | `wallet_ovo`     | IDR          | Not Supported | T+2            | 100        | 20,000,000  |
    | [ShopeePay](https://shopeepay.co.id/) | `wallet_shopee`  | IDR          | Full          | T+2            | 100        | 20,000,000  |
    | [LinkAja](https://linkaja.id/)        | `wallet_linkaja` | IDR          | Full          | T+2            | 100        | 20,000,000  |
  </Tab>

  <Tab title="🇹🇭 Thailand">
    | **Channel** | Code               | **Currency** | **Refund**        | **Settlement** | Min Amount | Max Amount |
    | :---------- | ------------------ | :----------- | :---------------- | :------------- | :--------- | ---------- |
    | Alipay      | `wallet_ali`       | THB          | Not supported     | T+2            | 1          | 50,000     |
    | WeChat Pay  | `wallet_wechat`    | THB          | Not supported     | T+2            | 1          | 70,000     |
    | TrueMoney   | `wallet_truemoney` | THB          | Not supported     | T+2            | 1          | 50,000     |
    | LINE Pay    | `wallet_line`      | THB          | 3-5 business days | T+2            | 1          | 50,000     |
  </Tab>
</Tabs>

## Payment Flow

Generally, wallet payments follow two types of flows: **redirection (jump app)** or **push notification**.

The diagram below illustrates a simplified architecture of how Monxa, the merchant, and the wallet provider interact.

<Tabs>
  <Tab title="Redirection Flow">
    ```mermaid theme={null}
    ---
    config:
      look: neo
    ---
    sequenceDiagram
      participant Customer as Customer
      participant Merchant as Merchant
      participant Monxa as Monxa
      participant Wallet as e-Wallet Provider
      autonumber
      Customer ->> Merchant: Checkout a transaction using E-Wallet
      Merchant ->> Monxa: Create E-Wallet transaction
      Monxa ->> Wallet: Initiate payment
      Wallet ->> Monxa: Return e-wallet URL
      Monxa ->> Merchant: Return e-wallet URL
      Merchant ->> Customer: Return e-wallet URL
      Customer ->> Wallet: Open e-wallet URL & input PIN/OTP
      Wallet ->> Wallet: Process the payment
      opt Success
        Wallet ->> Monxa: Notify success (callback)
        Monxa ->> Monxa: Update transaction to success
        Monxa ->> Merchant: Notify success (callback)
        Merchant ->> Monxa: Update transaction to success
        Monxa ->> Merchant: Settle fund to balance
        Merchant ->> Customer: Show transaction successful
      end
    ```
  </Tab>

  <Tab title="Push Notification Flow">
    ```mermaid theme={null}
    ---
    config:
      look: neo
    ---
    sequenceDiagram
      participant Customer as Customer
      participant Merchant as Merchant
      participant Monxa as Monxa
      participant Wallet as e-Wallet Provider

      autonumber
      Customer ->> Merchant: Checkout a transaction using E-Wallet
      Merchant ->> Monxa: Create E-Wallet transaction
      Monxa ->> Wallet: Initiate payment
      Wallet ->> Customer: Push notification to mobile app
      Customer ->> Wallet: Approve payment via app (PIN/OTP/biometric)
      Wallet ->> Wallet: Process the payment
      opt Success
        Wallet ->> Monxa: Notify success (callback)
        Monxa ->> Monxa: Update transaction to success
        Monxa ->> Merchant: Notify success (callback)
        Merchant ->> Monxa: Update transaction to success
        Monxa ->> Merchant: Settle fund to balance
        Merchant ->> Customer: Show transaction successful
      end
    ```
  </Tab>
</Tabs>

### Step 1: Create a Charge

<Tip>
  **Endpoint: POST v1/charges**
</Tip>

<AccordionGroup>
  <Accordion title="Request Example : Charge‑only (DANA)">
    ```bash theme={null}
    curl https://api.monxa.io/v1/charges \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: chg-12345-unique-key" \
      -d '{
        "amount": 150000,
        "currency": "IDR",
        "channel_code": "dana",
    	"channel_properties": {
    		"return_url": ""
    	}
        "reference_id": "INV-240001",
        "metadata": { "field_1": "A1234", field_2: "user@example.com" }
      }'
    ```
  </Accordion>

  <Accordion title="Response Example">
    ```json theme={null}
    {
      "id": "chg_01JAB1XYN01P3",
      "reference_id": "INV-240001",
      "amount": 150000,
      "currency": "IDR",
      "status": "pending",
      "channel_code": "dana",
      "actions": {
        "type": "REDIRECT_CUSTOMER",
       	"redirect_url": "",
        "expires_at": "2025-10-07T09:15:00Z"
      },
      "created_at": "2025-10-07T09:10:00Z"
    }
    ```
  </Accordion>
</AccordionGroup>

### Step 2: Redirect Customer to Wallet

After creating the payment request, use the response data to generate a QR code and present it to the user.

### Step 3: Customer Authorizes Payment

After creating the payment request, use the response data to generate a QR code and present it to the user.

### Step 4: Handle Webhooks & Update Payment Status

Monxa will send an asynchronous webhook to your configured endpoint:

**Handling Logic (Merchant Side)**

* On `SUCCESS`: mark order paid, fulfill goods
* On `FAILED` or `CANCELLED`: notify user, optionally prompt fallback
* On `PENDING`: you may poll or await final callback

<Tip>
  **Tip:** For general information on webhooks and best practices for handling them, refer to the [Webhook Guide ](/integration/webhooks)page.
</Tip>

<AccordionGroup>
  <Accordion title="Webhook Parameters">
    | **Parameter**        | **Description**                                                                  | **Example Value**              |
    | :------------------- | :------------------------------------------------------------------------------- | :----------------------------- |
    | `payment_id`         | Unique identifier of the payment.                                                | `pay_1234567890`               |
    | `payment_request_id` | Unique identifier of the payment request.                                        | `req_0987654321`               |
    | `phone`              | Buyer’s phone number.                                                            | `+6591234567`                  |
    | `amount`             | Amount related to the payment.                                                   | `100.00`                       |
    | `currency`           | Currency of the payment.                                                         | `SGD`                          |
    | `status`             | Payment status (`completed` / `failed`).                                         | `completed`                    |
    | `reference_number`   | Custom reference number mapped during payment request creation.                  | `ORDER12345`                   |
    | `hmac`               | Message Authentication Code (MAC) of this webhook request (used for validation). | `a1b2c3d4e5f67890abcdef123456` |
  </Accordion>

  <Accordion title="Sample Webhook (charge.succeeded)" />
</AccordionGroup>

## Refunds / Reversal

Refunds for e-wallet payments depend on the **capabilities of the wallet provider**.\
Some wallets support **full or partial refunds** through Monxa’s API, while others **do not allow refunds** and require a manual refund process outside the system.

* **Supported wallets** → You can request a **full or partial refund** via Monxa’s `/v1/refunds` endpoint. The provider will process the reversal and return the funds to the customer’s wallet balance.
* **Unsupported wallets** → Refunds are **not available through the API**. Merchants must perform a **manual refund** (e.g., bank transfer, store credit, or direct arrangement with the customer).
* **Webhook notifications** → For supported wallets, Monxa will notify you of refund status updates via events such as `refund.succeeded` or `refund.failed`.

<Tip>
  **Endpoint: POST v1/refunds**
</Tip>

<AccordionGroup>
  <Accordion title="Refund Request Example">
    ```bash theme={null}
    curl https://api.monxa.io/v1/refunds \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: ref-12345-unique-key" \
      -d '{
        "charge_id": "chg_01JAB1XYN01P3",
        "currency": "IDR",
        "amount": "50000",
        "reference_id": "INV-240001",
    	"description": "",
        "metadata": { "field_1": "A1234", field_2: "user@example.com" }
      }'
    ```
  </Accordion>

  <Accordion title="Response Example (refund.succeeded)">
    ```json theme={null}
    {
      "id": "ref_01JAB1XYN01P3",
      "reference_id": "INV-240001",
      "amount": 150000,
      "currency": "IDR",
      "status": "pending",
      "channel_code": "dana",
      "actions": {
        "type": "REDIRECT_CUSTOMER",
       	"redirect_url": "",
        "expires_at": "2025-10-07T09:15:00Z"
      },
      "created_at": "2025-10-07T09:10:00Z"
    }
    ```
  </Accordion>
</AccordionGroup>

<Warning>
  **Important**: Always check the wallet’s capabilities in Monxa’s dashboard or API documentation. The refund feature may vary by provider and by country.
</Warning>

## Merchant Best Practices

* Place e-wallet options prominently in checkout, especially in regions where they are popular
* Use deep linking / SDK embed flows to minimize context switching
* Pre-validate wallet availability (region, currency, user status) before initiating the flow
* Handle `PENDING` status gracefully (polling, UI feedback)
* Log analytics around wallet provider, time to approve, dropoffs
* Provide alternative payment options if e-wallet fails
* If refund-to-wallet isn’t supported, define clear fallback behavior (e.g. bank refund)
* Be cautious of transaction limits (some wallets limit per day / per transaction)
* Test across multiple devices, network conditions, and wallet states (e.g. insufficient balance)
