# OVO Recurring

***

## Requirements <a href="#requirements" id="requirements"></a>

1. Client ID / Secret Key from OVO
2. DOKU account. To access DOKU API, you need DOKU client id & DOKU client key that you can find in DOKU back office.

## Integration Flow <a href="#integration-flow" id="integration-flow"></a>

Here is the overview flow for OVO Recurring :

<figure><img src="/files/lIANBCOEi3TEaYNLlfdl" alt=""><figcaption></figcaption></figure>

***

## API list <a href="#api-list" id="api-list"></a>

Here is the sample of request header to implement every API list below :

```
Client-Id: MCH-0001-10791114622547
Request-Id: 15022aab-444f-4b04-afa8-ddfce89432ec
Request-Timestamp: 2020-08-11T08:45:42Z
Signature: HMACSHA256=vl9DBTX5KhEiXmnpOD0TSm8PYQknuHPdyHSTSc3W6Ps=
```

#### Request Header Explanation

| Parameter             | Description                                                                                                                                                                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Client-Id**         | Client ID retrieved from DOKU Back Office                                                                                                                                                                                                                                                           |
| **Request-Id**        | Unique random string (max 128 characters) generated from merchant side to protect duplicate request                                                                                                                                                                                                 |
| **Request-Timestamp** | Timestamp request on UTC time in ISO8601 UTC+0 format. It means to proceed transaction on UTC+7 (WIB), merchant need to subtract time with 7. Ex: to proceed transaction on September 22th 2020 at 08:51:00 WIB, the timestamp should be 2020-09-22T01:51:00Z                                       |
| **Signature**         | Security parameter that needs to be generated on merchant Backend and placed to the header request to ensure that the request is coming from valid merchant. Please refer to [this section](https://dashboard.doku.com/docs/docs/technical-references/generate-signature) to generate the signature |

Merchant and DOKU must validate signature in API list, see how to generate signature. You can refer to Generate Signature.

***

### Customer Binding <a href="#customer-binding" id="customer-binding"></a>

Merchant can binding OVO account to customer id, each OVO account can only binding to one customer on one merchant. Customer need to verify OTP and input PIN on OVO page.

**API Request**

| Type                          | Value                                                |
| ----------------------------- | ---------------------------------------------------- |
| **HTTP Method**               | POST                                                 |
| **API endpoint (Sandbox)**    | `https://api-sandbox.doku.com/ovo-open-api/v1/token` |
| **API endpoint (Production)** | `https://api.doku.com/ovo-open-api/v1/token`         |

Here is the overview flow for OVO Recurring Customer Binding :

<details>

<summary>Direct API - OVO Recurring - Customer Binding Sequence Diagram</summary>

</details>

Here is the sample of request body to binding OVO account to customer id :

```json
{
    "customer": {
        "id": "CUST_UAT_31",
        "name": "QA Shifter OVO Recurring",
        "phone": "087123123021",
        "email": "cobacobacoba9999@gmail.com",
        "additional_info": "None"
    },
    "ovo_account": {
        "account_email": "cobacobacoba9999@gmail.com",
        "account_mobile_phone": "6287123123021",
        "success_registration_url": "https://sandbox.doku.com/bo/login",
        "failed_registration_url": "https://www.seleniumeasy.com/test"
    },
    "service_type": "RECURRING"
}
```

#### Request Body Explanation

<table><thead><tr><th width="181">Parameter</th><th>Type</th><th>Mandatory</th><th>Description</th></tr></thead><tbody><tr><td><code>customer.id</code></td><td><code>string (50)</code></td><td>Mandatory</td><td>Merchant customer id</td></tr><tr><td><code>customer.name</code></td><td><code>string (70)</code></td><td>Optional</td><td>Customer name</td></tr><tr><td><code>customer.email</code></td><td><code>string (255)</code></td><td>Optional</td><td>Customer email</td></tr><tr><td><code>customer.phone</code></td><td><code>string (20)</code></td><td>Optional</td><td>Customer phone number</td></tr><tr><td><code>customer.additional_info</code></td><td><code>string (20)</code></td><td>Optional</td><td>Customer additional info</td></tr><tr><td><code>ovo_account.account_mobile_phone</code></td><td><code>string (20)</code></td><td>Mandatory</td><td>Register phone number on OVO</td></tr><tr><td><code>ovo_account.success_registration_url</code></td><td><code>string (2048)</code></td><td>Mandatory</td><td>URL for direct page after success register</td></tr><tr><td><code>ovo_account.failed_registration_url</code></td><td><code>string (2048)</code></td><td>Mandatory</td><td>URL for direct page after failed register</td></tr><tr><td><code>service_type</code></td><td><code>string (255)</code></td><td>Mandatory</td><td>Service Type, please input <code>RECURRING</code></td></tr></tbody></table>

**API Response**

After hitting the above API request, DOKU will give the response.

| Type            | Value   |
| --------------- | ------- |
| **HTTP Status** | 201     |
| **Result**      | SUCCESS |

Here is the sample of response body:

```json
{
    "customer": {
        "id": "CUSTOMER_OVOxDOKU",
        "name": "TESTINGQA",
        "email": "test@gmail.com",
        "phone": "087872180555",
        "additional_info": "None"
    },
    "ovo_account": {
        "registration_url": "https://jokul.doku.com/ovo-open-api/registration/sessionId/27817263817263817263817",
        "status": "PENDING",
    }
}
```

#### Response Body Explanation

| Parameter                          | Type            | Mandatory | Description                                                                                       |
| ---------------------------------- | --------------- | --------- | ------------------------------------------------------------------------------------------------- |
| `customer.id`                      | `string (50)`   | Mandatory | Merchant customer id                                                                              |
| `customer.name`                    | `string (70)`   | Optional  | Customer name                                                                                     |
| `customer.email`                   | `string (255)`  | Optional  | Customer email                                                                                    |
| `customer.phone`                   | `string (20)`   | Optional  | Customer phone number                                                                             |
| `customer.additional_info`         | `string (20)`   | Optional  | Customer additional info                                                                          |
| `ovo_account.account_mobile_phone` | `string (20)`   | Mandatory | Register phone number on OVO                                                                      |
| `ovo_account.registration_url`     | `string (2048)` | Mandatory | URL from DOKU for Customer to binding their account                                               |
| `ovo_account.status`               | `string`        | Mandatory | Always `PENDING` for Successfull token request (waiting for OTP verification & PIN vervification) |

***

### Get List Token (OVO) <a href="#get-list-token-ovo" id="get-list-token-ovo"></a>

After successful account linkage, merchant can get OVO token that can be used for that customer to payment using OVO. Token is created by DOKU, and valid for 1 year.

**API Request**

| Type                          | Value                                                 |
| ----------------------------- | ----------------------------------------------------- |
| **HTTP Method**               | POST                                                  |
| **API endpoint (Sandbox)**    | `https://api-sandbox.doku.com/tokenization/v1/tokens` |
| **API endpoint (Production)** | `https://api.doku.com/tokenization/v1/tokens`         |

Here is the sample of request body to get Token for OVO :

```json
{
    "customer" : {
        "id" : "CUST_UAT_31"
    },
    "token_data": {
        "type": "WALLET_RECURRING"
    }
}
```

| Parameter         | Type          | Mandatory | Description                                                                                    |
| ----------------- | ------------- | --------- | ---------------------------------------------------------------------------------------------- |
| `customer.id`     | `string (50)` | Mandatory | Customer id that already have active token                                                     |
| `token_data.type` | `string`      | Optional  | `DIRECT_DEBIT` / `CREDIT_CARD` / `WALLET` / `WALLET_RECURRING`, if not specified get all token |

**API Response**

After hitting the above API request, DOKUwill give the response.

| Type            | Value   |
| --------------- | ------- |
| **HTTP Status** | 200     |
| **Result**      | SUCCESS |

```json
{
    "customer": {
        "id": "CUST_UAT_31",
        "name": "QA Shifter OVO Recurring"
    },
    "token_data": {
        "type": "WALLET_RECURRING"
    },
    "wallet": {
        "issuer": "OVO",
        "token_id": "c15d437b56b918abaa3951b0beb48a57",
        "masked_phone_number": "****3021"
    }
}
```

#### Response Body Explanation

| Parameter                    | Type           | Mandatory | Description                                                               |
| ---------------------------- | -------------- | --------- | ------------------------------------------------------------------------- |
| `customer.id`                | `string (50)`  | Mandatory | Merchant customer id                                                      |
| `customer.name`              | `string (70)`  | Optional  | Customer name                                                             |
| `token_data.type`            | `string`       | Mandatory | Token Type : `CREDIT CARD`, `DIRECT DEBIT` , `WALLET`, `WALLET_RECURRING` |
| `wallet.issuer`              | `string (255)` | Mandatory | Issuer for wallet binding                                                 |
| `wallet.token_id`            | `string (128)` | Mandatory | Token generated by DOKU                                                   |
| `wallet.masked_phone_number` | `string (8)`   | Mandatory | Phone number masked                                                       |

***

### Get Account Balance <a href="#get-account-balance" id="get-account-balance"></a>

This balance check API allows users to check their latest OVO balance. The user should be able to access their balance at any time so they can make accurate and up to date decision regarding their transactions.

**API Request**

| Type                          | Value                                                  |
| ----------------------------- | ------------------------------------------------------ |
| **HTTP Method**               | POST                                                   |
| **API endpoint (Sandbox)**    | `https://api-sandbox.doku.com/ovo-open-api/v1/balance` |
| **API endpoint (Production)** | `https://api.doku.com/ovo-open-api/v1/balance`         |

Here is the sample of request body to get balance for OVO :

```json
{
    "customer": {
        "id": "1232131321"
    },
    "ovo_account": {
        "token_id": "fc72c4b0aedff916ab92e39cb80d3111"
    }
}
```

#### Request Body Explanation

| Parameter              | Type           | Mandatory | Description                                |
| ---------------------- | -------------- | --------- | ------------------------------------------ |
| `customer.id`          | `string (64)`  | Mandatory | Customer id that already have active token |
| `ovo_account.token_id` | `string (128)` | Mandatory | Token generated by DOKU                    |

**API Response**

After hitting the above API request, DOKUwill give the response.

| Type            | Value   |
| --------------- | ------- |
| **HTTP Status** | 201     |
| **Result**      | SUCCESS |

```json
{
    "customer": {
        "id": "1232131321",
        "name": "Joko",
        "email": "joko@gmail.com",
        "phone": "081287458232",
        "additional_info": ""
    },
    "ovo_account" : {
        "ovo_cash_balance" : 100000,
        "ovo_point_balance" : 100000
    }
}
```

#### Response Body Explanation

| Parameter                       | Type           | Mandatory | Description              |
| ------------------------------- | -------------- | --------- | ------------------------ |
| `customer.id`                   | `string (50)`  | Mandatory | Merchant customer id     |
| `customer.name`                 | `string (70)`  | Optional  | Customer name            |
| `customer.email`                | `string (255)` | Optional  | Customer email           |
| `customer.phone`                | `string (20)`  | Optional  | Customer phone number    |
| `customer.additional_info`      | `string (20)`  | Optional  | Customer additional info |
| `ovo_account.ovo_cash_balance`  | `number (10)`  | Mandatory | OVO Cash Balance         |
| `ovo_account.ovo_point_balance` | `number (10)`  | Mandatory | OVO Point Balance        |

***

### Payment Using Token <a href="#payment-using-token" id="payment-using-token"></a>

Payment using OVO token from OVO cash balance or/and OVO point balance. When OVO have program for payment using OVO point, customer can paying using OVO point balance on merchant. Payment using mixed OVO point and OVO cash, OVO point will be deducted first and the remaining will be deducted from OVO cash. Customer need to verify payment by input PIN on OVO page.

**API Request**

<table><thead><tr><th width="251">Type</th><th>Value</th></tr></thead><tbody><tr><td><strong>HTTP Method</strong></td><td>POST</td></tr><tr><td><strong>API endpoint (Sandbox)</strong></td><td><code>https://api-sandbox.doku.com/ovo-open-api/v1/payment-recurring</code></td></tr><tr><td><strong>API endpoint (Production)</strong></td><td><code>https://api.doku.com/ovo-open-api/v1/payment-recurring</code></td></tr></tbody></table>

#### OVO Recurring - Payment Flow Sequence Diagram

Here is the overview flow for OVO Recurring Payment Flow :

<figure><img src="/files/KBiYnS9AukyhOBNMOzMc" alt=""><figcaption></figcaption></figure>

Here is the sample of request body to do payment using OVO Token :

```json
{
    "customer": {
        "id": "CUST_UAT_31",
        "name": "QA Shifter OVO Recurring",
        "phone": "087123123021",
        "email": "cobacobacoba9999@gmail.com",
        "additional_info": "None"
    },
    "additional_info": { 
    },
    "order": {
        "invoice_number": "INVR_2021_7105",
        "line_items": [
            {
                "name": "Netflix",
                "price": 5000,
                "quantity": 1
            }
        ],
        "amount": "100000"
    },
    "ovo_account": {
        "token_id": "c15d437b56b918abaa3951b0beb48a57",
        "payment_use_ovo_point": false,
        "first_payment": false
    }
}
```

#### Request Body Explanation

| Parameter                           | Type           | Mandatory | Description                                                                                                        |
| ----------------------------------- | -------------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
| `customer.id`                       | `string (50)`  | Mandatory | Merchant customer id                                                                                               |
| `customer.name`                     | `string (70)`  | Optional  | Customer name                                                                                                      |
| `customer.email`                    | `string (255)` | Optional  | Customer email                                                                                                     |
| `customer.phone`                    | `string (20)`  | Optional  | Customer phone number                                                                                              |
| `customer.additional_info`          | `string (255)` | Optional  | Customer additional info                                                                                           |
| `additional_info`                   | `Json`         | Optional  | additional info                                                                                                    |
| `order.invoice_number`              | `string (32)`  | Mandatory | Merchant transaction id unique per client id, only accept alphanumeric, \_ and - Min length is 3, max length is 32 |
| `order.line_items.name`             | `string`       | Optional  | Privacy concern so optional, but if send will help our risk engine                                                 |
| `order.line_items.price`            | `number`       | Optional  | Privacy concern so optional, but if send will help our risk engine                                                 |
| `order.line_items.quantity`         | `number`       | Mandatory | Privacy concern so optional, but if send will help our risk engine                                                 |
| `order.amount`                      | `number (10)`  | Mandatory | Converted total amount.                                                                                            |
| `ovo_account.token_id`              | `string (128)` | Mandatory | OVO E-Wallet Token                                                                                                 |
| `ovo_account.payment_use_ovo_point` | `string (5)`   | Optional  | Default false, if True will use all OVO Point first before use OVO Cash                                            |
| `ovo_account.first_payment`         | `Boolean`      | Optional  | True. if this transaction is first payment of subcription                                                          |

**API Response**

After hitting the above API request, DOKUwill give the response.

| Type            | Value   |
| --------------- | ------- |
| **HTTP Status** | 201     |
| **Result**      | SUCCESS |

```json
{
    "customer": {
        "id": "CUST_UAT_31",
        "name": "QA Shifter OVO Recurring",
        "email": "cobacobacoba9999@gmail.com",
        "phone": "087123123021",
        "additional_info": "None"
    },
    "additional_info": {},
    "order": {
        "invoice_number": "INVR_2021_7105",
        "line_items": [
            {
                "name": "Netflix",
                "price": 5000,
                "quantity": 1
            }
        ],
        "amount": 100000
    },
    "payment": {
        "status": "SUCCESS"
    }
}
```

#### Response Body Explanation

| Parameter                   | Type           | Mandatory | Description                                                                                                                                                                  |
| --------------------------- | -------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customer.id`               | `string (50)`  | Mandatory | Merchant customer id                                                                                                                                                         |
| `customer.name`             | `string (70)`  | Optional  | Customer name                                                                                                                                                                |
| `customer.email`            | `string (255)` | Optional  | Customer email                                                                                                                                                               |
| `customer.phone`            | `string (20)`  | Optional  | Customer phone number                                                                                                                                                        |
| `customer.additional_info`  | `string (20)`  | Optional  | Customer additional info                                                                                                                                                     |
| `additional_info`           | `Json`         | Optional  | additional info                                                                                                                                                              |
| `order.invoice_number`      | `string (32)`  | Mandatory | Merchant transaction id unique per client id, only accept alphanumeric, \_ and - Min length is 3, max length is 32                                                           |
| `order.line_items.name`     | `string`       | Optional  | Privacy concern so optional, but if send will help our risk engine                                                                                                           |
| `order.line_items.price`    | `number`       | Optional  | Privacy concern so optional, but if send will help our risk engine                                                                                                           |
| `order.line_items.quantity` | `number`       | Mandatory | Privacy concern so optional, but if send will help our risk engine                                                                                                           |
| `order.amount`              | `number (10)`  | Mandatory | Converted total amount.                                                                                                                                                      |
| `payment.status`            | `string`       | Mandatory | PENDING for successful token request (waiting for OTP verification) / SUCCESS if not need OTP, TOKEN\_EXPIRED (need to input PIN twice and still can proceed to transaction) |

***

### Refund <a href="#refund" id="refund"></a>

Refund OVO transaction. For payment using mixed OVO cash and OVO point, OVO point will be refunded first.

**API Request**

| Type                          | Value                                                         |
| ----------------------------- | ------------------------------------------------------------- |
| **HTTP Method**               | POST                                                          |
| **API endpoint (Sandbox)**    | `https://api-sandbox.doku.com/ovo-open-api/v1/payment-refund` |
| **API endpoint (Production)** | `https://api.doku.com/ovo-open-api/v1/payment-refund`         |

Here is the sample of request body to do refund for OVO Transaction :

```json
{
    "order": {
        "invoice_number": "INV_NUMBER_D009"
    },
    "payment": {
        "original_request_id":"82014"
    },
    "refund": {
        "amount": 1000,
        "reason":"Cancel Order"
    }
}
```

#### Request Body Explanation

| Parameter                     | Type           | Mandatory | Description                                                                        |
| ----------------------------- | -------------- | --------- | ---------------------------------------------------------------------------------- |
| `order.invoice_number`        | `string (32)`  | Mandatory | Invoice number of the transaction that being refunded, same as the request payment |
| `payment.original_request_id` | `string (128)` | Mandatory | Request ID from Payment Initiation of the transaction that being refunded          |
| `refund.amount`               | `number`       | Mandatory | Transaction amount that wants to be refunded                                       |
| `refund.reason`               | `string (255)` | Optional  | Reason refund                                                                      |

**API Response**

After hitting the above API request, DOKUwill give the response.

| Type            | Value   |
| --------------- | ------- |
| **HTTP Status** | 201     |
| **Result**      | SUCCESS |

```json
{
    "order": {
        "invoice_number": "INV_NUMBER_D009"
    },
    "payment": {
        "original_request_id": "82014"
    },
    "refund": {
        "amount": 1000,
        "reason": "Cancel Order",
        "status": "SUCCESS",
        "message": "SUCCESS"
    }
}
```

#### Response Body Explanation

| Parameter                     | Type           | Mandatory | Description             |
| ----------------------------- | -------------- | --------- | ----------------------- |
| `order.invoice_number`        | `string (32)`  | Mandatory | Same as the request     |
| `payment.original_request_id` | `string (128)` | Mandatory | Same as the request     |
| `refund.amount`               | `number`       | Mandatory | Amount to be refunded   |
| `refund.reason`               | `string (255)` | Optional  | Reason refund           |
| `refund.status`               | `string`       | Mandatory | SUCCESS / FAILED        |
| `refund.message`              | `string (10)`  | Optional  | Reason if failed refund |

***

### Unbind Linked Account <a href="#unbind-linked-account" id="unbind-linked-account"></a>

Customer should always have option to unlink their OVO account from any merchant.

**API Request**

| Type                          | Value                                                       |
| ----------------------------- | ----------------------------------------------------------- |
| **HTTP Method**               | POST                                                        |
| **API endpoint (Sandbox)**    | `https://api-sandbox.doku.com/ovo-open-api/v1/token-delete` |
| **API endpoint (Production)** | `https://api.doku.com/ovo-open-api/v1/token-delete`         |

Here is the sample of request body to unlink their OVO Account :

```
{
    "customer": {
        "id": "TEST-CIMBXDOKU-05",
        "name":" "
    },
    "ovo_account": {
        "token_id": "1614dc147e404f41f6d2de877fda1f94"
    }
}
```

#### Request Body Explanation

| Parameter              | Type           | Mandatory | Description                                                            |
| ---------------------- | -------------- | --------- | ---------------------------------------------------------------------- |
| `customer.id`          | `string (50)`  | Mandatory | Merchant id                                                            |
| `customer.name`        | `string (50)`  | Mandatory | Merchant name                                                          |
| `ovo_account.token_id` | `string (128)` | Mandatory | Token created from register ovo account that owned by this customer id |

**API Response**

After hitting the above API request, DOKUwill give the response.

| Type            | Value   |
| --------------- | ------- |
| **HTTP Status** | 201     |
| **Result**      | SUCCESS |

```json
{
    "customer": {
        "id": "TEST-CIMBXDOKU-05",
        "name": "DOKUXCIMB"
    },
    "ovo_account": {
        "token_id": "1614dc147e404f41f6d2de877fda1f94",
        "status": "SUCCESS",
        "message": "Success Unbinding Ovo Account"
    }
}
```

#### Response Body Explanation

| Parameter              | Type           | Mandatory | Description                                                            |
| ---------------------- | -------------- | --------- | ---------------------------------------------------------------------- |
| `customer.id`          | `string (50)`  | Mandatory | Merchant id                                                            |
| `customer.name`        | `string (50)`  | Mandatory | Merchant name                                                          |
| `ovo_account.token_id` | `string (128)` | Mandatory | Token created from register ovo account that owned by this customer id |
| `ovo_account.status`   | `string`       | Mandatory | DELETED Token                                                          |
| `ovo_account.message`  | `string`       | Optional  | SUCCESS unbind token\_id from customer                                 |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.doku.com/archive/non-snap/e-wallet/ovo-recurring.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
