# Batch Upload

For merchants who have their own billing schedule, DOKU have this feature to make batch payments according to the data the merchant uploads. It is a one time transaction to automatically charged your customer without scheduler. You can adjust when the deduction running from column "Execute Date" in template that you upload.

There are two channels for DOKU Account Billing Batch Upload: Back Office or SFTP. This document are specific for merchants that connect with DOKU Account Billing by SFTP.

Here is the overview of how to integrate with DOKU Account Billing Batch Upload SFTP:

1. First payment
2. Get Token List
3. Upload SFTP
4. Merchant notify DOKU (optional)
5. DOKU notify Merchant when report available
6. Download SFTP report file

<figure><img src="/files/1y883m14i9ibHaifHJYQ" alt=""><figcaption><p>Account Billing Batch Upload</p></figcaption></figure>

## First Payment and Get Token List

Create first payment with credit or debit card, direct debit, or e-wallet. Then get token from API get token list. Token is binding from customer payment credential & customer id. Customer id can be filled with billing number. Save token as data in file upload.

Direct API availability for first payment:

1. [Credit Card](/accept-payments/direct-api/non-snap/cards.md)
2. [Direct Debit](/accept-payments/direct-api/snap/integration-guide/direct-debit/bri-direct-debit.md) (BRI)
3. [E-Wallet](/accept-payments/direct-api/snap/integration-guide/e-wallet/ovo.md) (OVO)

API Token:

1. [Get Token List](/archive/non-snap/tokenization-v1.md)

## SFTP Flow

<figure><img src="/files/P82GaaMHqrgD0JsMMdn4" alt="" width="375"><figcaption><p>SFTP Flow</p></figcaption></figure>

### Access&#x20;

DOKU will create user access for merchants to Read & Write in SFTP DOKU according the environment. Merchants will send their IP for DOKU Whitelist.

### Encrypt File

Phase encryption

1. File encrypted with AES 256 using symmetric key
2. This symmetric key being encrypted using Public-Private Key
3. DOKU generate Public-Private Key. (this need to be changed annually / bi-annually)
4. DOKU share the Public Key to Merchant and store the Private Key

<figure><img src="/files/6yrw6wNsTI9HCHDVXVLI" alt="" width="375"><figcaption><p>Encryption Process</p></figcaption></figure>

Procedure:&#x20;

1. Merchants generate random Symmetric Key using SALT.
2. Merchants encrypt file data with AES 256 using the generated Symmetric Key.
3. Merchants encrypt the generate Symmetric Key using Public Key given by DOKU type RSA No Padding.
4. Merchants append Encrypted Symmetric Key into the Encrypted File.
5. Merchants append length Symmetric Key 4 String at front ( 128 ).

### Folder

After connected to DOKU SFTP, merchants got folders with different function according to the folder name.

<figure><img src="/files/wbJI9a6y8lRmAOSE5umx" alt=""><figcaption><p>Folder Structure</p></figcaption></figure>

* download ( Batch Upload Transaction )

  Folder for merchants to upload file to be executed on Batch Upload. The file 'ExampleBatch.txt' contains sample data that the merchant needs to provide for DOKU to retrieve and process.
* upload ( Report Batch Upload Transaction )

  Folder for merchants to get report of Batch Upload Transaction.

### SFTP File

#### Batch File

Before put file in SFTP, first we need to setup the file it self. You will need to create it in TXT Format. Please be sure to include the prefix "TKN" in the file name.

Example file name: TKN\_202510ABC.TXT

<figure><img src="/files/HtWXROww10ayjtKcqVQA" alt=""><figcaption><p>File Content Example</p></figcaption></figure>

<table><thead><tr><th valign="middle">Parameter</th><th width="177" valign="middle">Type</th><th valign="middle">Requirement</th><th valign="middle">Description</th></tr></thead><tbody><tr><td valign="middle">BILLING REF / BILLING NUMBER</td><td valign="middle">Alphanumeric(128)</td><td valign="middle">MANDATORY</td><td valign="middle">Merchant Unique ID</td></tr><tr><td valign="middle">DESCRIPTION</td><td valign="middle">Alphanumeric(256)</td><td valign="middle">OPTIONAL</td><td valign="middle">Billing Description</td></tr><tr><td valign="middle">INVOICE NUMBER</td><td valign="middle">Alphanumeric(64)</td><td valign="middle">MANDATORY</td><td valign="middle">Invoice Number</td></tr><tr><td valign="middle">CURRENCY</td><td valign="middle">Alpha(3)</td><td valign="middle">MANDATORY</td><td valign="middle">Only IDR Currency</td></tr><tr><td valign="middle">AMOUNT</td><td valign="middle">Numbers(10,2)</td><td valign="middle">MANDATORY</td><td valign="middle"><p>Example: </p><p>no decimal 10000<br>decimal 10000.00</p></td></tr><tr><td valign="middle">TOKEN</td><td valign="middle">Numbers(32)</td><td valign="middle">MANDATORY</td><td valign="middle">Credit / Debit / Direct Debit / E-Money Token</td></tr><tr><td valign="middle">CARD HOLDER NAME</td><td valign="middle">Alphanumeric(128)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer name</td></tr><tr><td valign="middle">CARD HOLDER EMAIL</td><td valign="middle">Alphanumeric(128)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer email</td></tr><tr><td valign="middle">CARD HOLDER PHONE</td><td valign="middle">Numbers(32)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer phone number</td></tr><tr><td valign="middle">CARD HOLDER CITY</td><td valign="middle">Alphanumeric(128)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer city location</td></tr><tr><td valign="middle">CARD HOLDER REGION</td><td valign="middle">Alphanumeric(128)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer region location</td></tr><tr><td valign="middle">CARD HOLDER COUNTRY</td><td valign="middle">Alpha(2)</td><td valign="middle">OPTIONAL</td><td valign="middle">Example: ID</td></tr><tr><td valign="middle">CARD HOLDER ADDRESS</td><td valign="middle">Alphanumeric(128)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer address</td></tr><tr><td valign="middle">CARD HOLDER POSTAL CODE</td><td valign="middle">Alphanumeric(16)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer postal code</td></tr><tr><td valign="middle">CARD HOLDER BIRTHDATE</td><td valign="middle">Numbers(8)</td><td valign="middle">OPTIONAL</td><td valign="middle">Customer birth date</td></tr><tr><td valign="middle">EXECUTE DATE</td><td valign="middle">Numbers(32)</td><td valign="middle">OPTIONAL</td><td valign="middle">Date transaction want to execute (YYYYMMDD)</td></tr></tbody></table>

#### Batch Report File

After transaction finish DOKU will generate report in TXT format, like Picture below. Merchant can get the data in the folder “upload”.

<figure><img src="/files/n9UQSUF6mx6dYsYkqSTO" alt=""><figcaption><p>Report File Example</p></figcaption></figure>

<table><thead><tr><th valign="top">Value</th><th>Parameter</th><th valign="top">Type</th></tr></thead><tbody><tr><td valign="top">48907854</td><td>TOTAL AMOUNT</td><td valign="top">Numbers(12)</td></tr><tr><td valign="top">200</td><td>TOTAL TRANSACTION</td><td valign="top">Numbers(11)</td></tr><tr><td valign="top">200</td><td>TOTAL SUCCESS</td><td valign="top">Numbers(11)</td></tr><tr><td valign="top">0</td><td>TOTAL FAILED</td><td valign="top">Numbers(11)</td></tr><tr><td valign="top">411111******7548</td><td>CARD NUMBER</td><td valign="top">NS(16)</td></tr><tr><td valign="top">DOKU1234567</td><td>INVOICE NUMBER</td><td valign="top">Alphanumeric(64)</td></tr><tr><td valign="top">200000</td><td>AMOUNT</td><td valign="top">Numbers(12,2)</td></tr><tr><td valign="top">IDR</td><td>CURRENCY</td><td valign="top">Alpha(3)</td></tr><tr><td valign="top">00</td><td>RESPONSE CODE</td><td valign="top">Alphanumeric(2)</td></tr><tr><td valign="top">SUCCESS</td><td>RESPONSE MESSAGE</td><td valign="top">Alphanumeric(256)</td></tr><tr><td valign="top">890123</td><td>APPROVAL CODE</td><td valign="top">Alphanumeric(16)</td></tr><tr><td valign="top">20170123121030</td><td>PAYMENT DATE TIME</td><td valign="top">Numbers(14)</td></tr><tr><td valign="top">100</td><td>BANK CODE</td><td valign="top">Numbers(3)</td></tr></tbody></table>

BANK CODE\
\- 100 : BNI\
\- 350 : BANK MANDIRI\
\- 400 : BCA\
\- 150 : BANK CIMB\
\- 151 : BRI

PAYMENT DATE TIME\
Sample : 20170123121030\
\- 2017 : YEAR\
\- 01 : MONTH\
\- 23 : DATE\
\- 12 : HOURS\
\- 10 : MINUTES\
\- 30 : SECONDS

## API Merchant notify to DOKU

After merchants put file data in SFTP, merchants will trigger DOKU to get data file in SFTP with this API. This request is optional.

#### Request

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

Here is the sample of request header to notify DOKU:

```
Client-Id: MCH-0001-10791114622547
Request-Id: b266c265-3d61-4708-9860-c0d5b9a98f8c
Request-Timestamp: 2020-08-11T08:45:42Z
Signature: HMACSHA256=9UPUFzOqJc47aJzD9ESOTcWg6TMsg3mqSP+DnUO8ENE=
```

<table><thead><tr><th width="199">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>client-id</code></strong></td><td>Client ID retrieved from DOKU Back Office</td></tr><tr><td><strong><code>request-id</code></strong></td><td>Unique random string (max 128 characters) generated from merchant side to protect duplicate request</td></tr><tr><td><strong><code>request-timestamp</code></strong></td><td>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</td></tr><tr><td><strong><code>signature</code></strong></td><td>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 <a href="/pages/VogdJfoJtS2yXvClOsrc">this section</a> to generate the signature</td></tr></tbody></table>

Here is the sample of request body to notify DOKU:

```json
{
    "file_name":"example.txt"
}
```

<table><thead><tr><th>Parameter</th><th>Data Type</th><th>Requirement</th><th width="241">Description</th></tr></thead><tbody><tr><td>file_name</td><td>String (128)</td><td>Mandatory</td><td>File name merchant put in DOKU sftp download folder</td></tr></tbody></table>

#### Response

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

| Type            | Value      |
| --------------- | ---------- |
| **HTTP Status** | 201        |
| **Result**      | IN PROCESS |

{% tabs %}
{% tab title="In Process" %}
HTTP Status `201 Created`

```json
{
    "name":"example.txt"
    "status":IN_PROCESS  
}
```

{% endtab %}

{% tab title="Signature not valid " %}
HTTP Status `400 Bad Request`

```json
{"error":{
    "code": "invalid_signature",
    "message": "invalid header signature",
    "type": "Invalid Signature"
    }
}
```

{% endtab %}

{% tab title="Invalid Parameter" %}
HTTP Status `400 Bad Request` &#x20;

```json
{"error":{
    "code": "invalid_parameter",
    "message": "file_name must not be empty",
    "type": "Not input object file_name"
    }
} 
```

{% endtab %}

{% tab title="Idempotent" %}
HTTP Status Code `400 Bad Request`

```json
{"error":{
    "code": "idempotent_request",
    "message": "idempotent request",
    "type": "Duplicate file name"
    }
}
```

{% endtab %}
{% endtabs %}

| Parameter     | Data Type    | Requirement | Description          |
| ------------- | ------------ | ----------- | -------------------- |
| name          | String (128) | Mandatory   | File name            |
| status        | String (128) | Mandatory   | IN\_PROCESS response |
| error.code    |              |             |                      |
| error.message |              |             |                      |
| error.type    |              |             |                      |

## API DOKU notify to Merchant

After DOKU create report in SFTP, DOKU will notify merchant to get report. Guide how to handle payment notification can refer to [this section](/get-started-with-doku-api/notification.md).

#### Request

| Type            | Value |
| --------------- | ----- |
| **HTTP Method** | POST  |

Here is the sample of request header DOKU send to merchant:

```
Client-Id: MCH-0001-10791114622547
Request-Id: b266c265-3d61-4708-9860-c0d5b9a98f8c
Request-Timestamp: 2020-08-11T08:45:42Z
Signature: HMACSHA256=9UPUFzOqJc47aJzD9ESOTcWg6TMsg3mqSP+DnUO8ENE=
```

Here is the sample of request body DOKU send to merchant:

```json
{
    "service":{
        "id":"BATCH_UPLOAD"
    },
    "batch_file":{
        "name":"example.txt",
        "status":"DONE",
        "date":"2021-07-29T13:52:53Z"
    }
}
```

| Parameter          | Data Type | Requeirement | Description                   |
| ------------------ | --------- | ------------ | ----------------------------- |
| service.id         |           | Mandatory    | Batch Upload Service          |
| batch\_file.name   |           | Mandatory    | Batch file Upload name        |
| batch\_file.status |           | Mandatory    | Status of processed file Done |
| batch\_file.date   |           | Mandatory    | Date file finish processed    |

## Batch Upload Executable Script for Merchant

### Encrypt Process

#### Encrypt Command Example:

java -jar target/tkn-utility.jar encrypt /users/jonathan/doku/project/jar-java/data/TEST\_FILE\_1.txt /users/jonathan/doku/project/jar-java/data/TEST\_FILE\_1.enc.txt /users/jonathan/doku/project/jar-java/key/PUBLICKEY\_120078\_20210115111404.key 012345678901234567890

#### Encrypt Command Explanation:

\<jar file> encrypt \<input file> \<output file> \<public key> \<salt>

Salt = Harus 21 karakter bebas

### Decrypt Process

#### Decrypt Command Example

java -jar target/tkn-utility.jar decrypt /users/jonathan/doku/project/jar-java/data/TEST\_FILE\_1.enc.txt /users/jonathan/doku/project/jar-java/data/TEST\_FILE\_1.dec.txt /users/jonathan/doku/project/jar-java/key/PRIVATEKEY\_120078\_20210115111404.key

#### Decrypt Command Explanation:

\<jar file> decrypt \<input file> \<output file> \<private key>


---

# 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/flexibill/account-billing/batch-upload.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.
