Skip to main content

💳 Thai Credit Card Statement OCR 🆕

💳 ใบแจ้งยอดบัตรเครดิตไทย

Version Status New

Welcome to the Thai Credit Card Statement OCR API, an AI-powered solution developed by iApp Technology Co., Ltd. for extracting data from Thai credit card statements. This documentation will help you integrate and use our OCR service effectively.

Try Demo!

Example Images (Click to try)

Example 1

Demo key is limited to 10 requests per day per IP
Click here to get your API key

Getting Started

  1. Prerequisites

    • An API key from iApp Technology
    • Thai credit card statement images
    • Supported file formats: JPEG, JPG, PNG, HEIC, HEIF, PDF
    • Maximum file size: 10MB
  2. Quick Start

    • Fast processing (5-10 seconds per document)
    • High accuracy text extraction
    • Support for multiple file formats
  3. Key Features

    • Detailed field extraction including:
      • Statement details (type, dates, card number)
      • Card holder information (name)
      • Bank information (name, address, tax ID, contact)
      • Transaction details (date, description, amount)
      • Financial summary (balances, payments, charges)
      • Reward points information
    • Support for both single-page and multi-page documents (PDF)
    • Option to return original OCR text and processed images
    • Flexible JSON response format with detailed field extraction
  4. Security & Compliance

    • GDPR and PDPA compliant
    • Secure API endpoints
    • No data retention after processing

Example

Here's a sample credit card statement and its extracted data:

Credit Card Statement Example

Request:

cURL

curl -X POST "https://api.iapp.co.th/ocr/v3/creditcard-statement/file" \
-H "apikey: YOUR_API_KEY" \
-F "file=@/path/to/creditcard-statement.jpg" \
-F "return_image=false" \
-F "return_ocr=false"
How to get API Key?

Please visit iApp AI Portal to view your existing API key or request a new one.

Response:

{
"message": "success",
"processed": {
"statementType": "ใบแจ้งยอดบัญชีบัตรเครดิต",
"statementDate": "31/12/2566",
"dueDate": "25/01/2567",
"cardNumber": "4711-XXXX-XXXX-1234",
"cardHolderName": "นาย ทดสอบ ระบบ",
"bankName": "ธนาคารกสิกรไทย จำกัด (มหาชน)",
"bankAddress": "1 ซอยราษฎร์บูรณะ 27/1 ถนนราษฎร์บูรณะ แขวงราษฎร์บูรณะ เขตราษฎร์บูรณะ กรุงเทพฯ 10140",
"bankTaxID": "0107536000315",
"bankPhone": "02-888-8888",
"bankFax": "02-888-8888",
"creditLimit": 100000.0,
"closingDate": "31/12/2566",
"newBalancePayment": 15789.4,
"minimumPaymentDue": 789.47,
"interestRate": 16.0,
"paymentByDebitAccountNo": "XXX-X-XX789-X",
"transactions": [
{
"transactionDate": "20/12",
"postingDate": "21/12",
"description": "CHOKCHAI STEAK HOUSE PATHUMTHANI THA",
"foreignAmount": null,
"foreignCurrencyCode": null,
"amountTHB": 1089.0
}
],
"payments_adjustment_others": [
{
"transactionDate": "31/12",
"postingDate": "31/12",
"description": "PAYMENT RECEIVED, THK YOU",
"foreignAmount": null,
"foreignCurrencyCode": null,
"amountTHB": -369.0
}
],
"previousBalance": 14789.4,
"thisPeriodBalance": 15789.4,
"totalPayments": 678.0,
"totalInterestCharges": 0.0,
"reward": {
"rewardAccumulatedPoints": 1234,
"rewardPointsEarned": 56,
"bonusPointsEarned": 0,
"pointsAdjustedThisMonth": 0,
"pointsRedeemed": 0,
"pointsOutstanding": 1290
},
"paymentBarcodeNo": "1234567890123456789"
},
"process_ms": 6821
}

Features & Capabilities

Core Features

  1. Document Processing

    • High accuracy text extraction and field recognition
    • Thai language support
    • Fast processing time of 5-10 seconds per document
    • Multi-format support (JPEG, JPG, PNG, HEIC, HEIF, PDF)
    • Multi-page document handling
    • Option to return original OCR text and processed images
    • GDPR and PDPA compliant processing
  2. Data Extraction

    • Flexible JSON response format with detailed field extraction

Supported Fields

FieldTypeDescription
statementTypeStringType of credit card statement
statementDateStringDate of statement
dueDateStringDue date for payment
cardNumberStringCredit card number
cardHolderNameStringName of card holder
bankNameStringName of issuing bank
bankAddressStringAddress of issuing bank
bankTaxIDStringTax ID of issuing bank
bankPhoneStringPhone number of bank
bankFaxStringFax number of bank
creditLimitNumberCredit limit amount
closingDateStringStatement closing date
newBalancePaymentNumberNew balance payment amount
minimumPaymentDueNumberMinimum payment due amount
interestRateNumberInterest rate percentage
paymentByDebitAccountNoStringLinked debit account number
transactionsArrayArray of transaction details
payments_adjustment_othersArrayArray of payment and adjustment details
previousBalanceNumberPrevious statement balance
thisPeriodBalanceNumberCurrent period balance
totalPaymentsNumberTotal payments made
totalInterestChargesNumberTotal interest charges
rewardObjectReward points information
paymentBarcodeNoStringPayment barcode number

Note: All currency values are rounded to two decimal places.

API Reference

Recognizing Credit Card Statement

There are two endpoints available for processing credit card statements:

1. File Upload

POST https://api.iapp.co.th/ocr/v3/creditcard-statement/file

Request Headers

NameTypeRequiredDescription
apikeystringYesYour API key

Request Body (multipart/form-data)

ParameterTypeRequiredDescription
filefileYesStatement image (JPEG, PNG) or PDF document
return_imagebooleanNoInclude base64 encoded image in response (default: false)
return_ocrbooleanNoInclude raw OCR text in response (default: false)

Error Handling

StatusCodeDescription
400BAD_REQUESTInvalid parameters or file format
401UNAUTHORIZEDInvalid or missing API key
404NOT_FOUNDInvalid endpoint
500INTERNAL_SERVER_ERRORProcessing failed

2. Base64 Image

POST https://api.iapp.co.th/ocr/v3/creditcard-statement/base64

Request Headers
NameTypeRequiredDescription
apikeystringYesYour API key
Request Body

You can send the base64 data either as JSON or form data:

JSON Format:

{
"base64_string": "string", // Base64 encoded image data
"return_image": false, // Optional
"return_ocr": false // Optional
}

Form Data Format:

ParameterTypeRequiredDescription
base64_stringstringYesBase64 encoded image data
return_imagebooleanNoInclude base64 encoded image in response (default: false)
return_ocrbooleanNoInclude raw OCR text in response (default: false)
Response Format

Same as file upload endpoint

Code Examples

Python (File Upload)

import requests
apiKey = 'YOUR_API_KEY'
filePath = '/path/to/creditcard-statement.jpg'
url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/file"

headers = {'apikey': apiKey}
files = {'file': ('creditcard-statement.jpg', open(filePath, 'rb'), 'image/jpeg')}
data = {'return_image': 'false', 'return_ocr': 'false'}

response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())

Python (Base64)

import requests
import base64

apiKey = 'YOUR_API_KEY'
filePath = '/path/to/creditcard-statement.jpg'
url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/base64"

# Read image file and convert to base64
with open(filePath, 'rb') as image_file:
base64_string = base64.b64encode(image_file.read()).decode()

headers = {
'apikey': apiKey,
'Content-Type': 'application/json'
}

data = {
'base64_string': base64_string,
'return_image': False,
'return_ocr': False
}

response = requests.post(url, headers=headers, json=data)
print(response.json())

Javascript (File Upload)

const axios = require("axios")
const FormData = require("form-data")
const fs = require("fs")

const apiKey = "YOUR_API_KEY"
const filePath = "/path/to/creditcard-statement.jpg"
const url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/file"

const form = new FormData()
form.append("file", fs.createReadStream(filePath))
form.append("return_image", "false")
form.append("return_ocr", "false")

try {
const response = await axios.post(url, form, {
headers: {
...form.getHeaders(),
apikey: apiKey,
},
})
return response.data
} catch (error) {
throw error
}

Javascript (Base64)

const axios = require('axios');
const fs = require('fs');

const apiKey = 'YOUR_API_KEY';
const filePath = '/path/to/creditcard-statement.jpg';
const url = 'https://api.iapp.co.th/ocr/v3/creditcard-statement/base64';

// Read image file and convert to base64
const base64String = fs.readFileSync(filePath, {encoding: 'base64'});

const data = {
base64_string: base64String,
return_image: false,
return_ocr: false
};

try {
const response = await axios.post(url, data, {
headers: {
'Content-Type': 'application/json',
'apikey': apiKey
}
});
return response.data;
} catch (error) {
throw error;
}

PHP (File Upload)

$url = 'https://api.iapp.co.th/ocr/v3/creditcard-statement/file';
$apiKey = 'YOUR_API_KEY';
$filePath = '/path/to/creditcard-statement.jpg';

$headers = array(
'apikey: ' . $apiKey
);

$postFields = array(
'file' => new CURLFile($filePath),
'return_image' => 'false',
'return_ocr' => 'false'
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

PHP (Base64)

$url = 'https://api.iapp.co.th/ocr/v3/creditcard-statement/base64';
$apiKey = 'YOUR_API_KEY';
$filePath = '/path/to/creditcard-statement.jpg';

// Read image file and convert to base64
$base64String = base64_encode(file_get_contents($filePath));

$data = array(
'base64_string' => $base64String,
'return_image' => false,
'return_ocr' => false
);

$headers = array(
'Content-Type: application/json',
'apikey: ' . $apiKey
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

Swift (File Upload)

import Foundation

let url = URL(string: "https://api.iapp.co.th/ocr/v3/creditcard-statement/file")!
let filePath = "/path/to/creditcard-statement.jpg"
let apiKey = "YOUR_API_KEY"

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue(apiKey, forHTTPHeaderField: "apikey")

let boundary = UUID().uuidString
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

var body = Data()
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"creditcard-statement.jpg\"\r\n".data(using: .utf8)!)
body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
body.append(try! Data(contentsOf: URL(fileURLWithPath: filePath)))
body.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"return_image\"\r\n\r\nfalse\r\n".data(using: .utf8)!)
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"return_ocr\"\r\n\r\nfalse\r\n".data(using: .utf8)!)
body.append("--\(boundary)--\r\n".data(using: .utf8)!)

request.httpBody = body

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("Error: \(error?.localizedDescription ?? "Unknown error")")
return
}
print(String(data: data, encoding: .utf8)!)
}

task.resume()

Swift (Base64)

import Foundation

let url = URL(string: "https://api.iapp.co.th/ocr/v3/creditcard-statement/base64")!
let filePath = "/path/to/creditcard-statement.jpg"
let apiKey = "YOUR_API_KEY"

// Read image file and convert to base64
guard let imageData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
print("Error reading file")
return
}
let base64String = imageData.base64EncodedString()

let parameters: [String: Any] = [
"base64_string": base64String,
"return_image": false,
"return_ocr": false
]

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(apiKey, forHTTPHeaderField: "apikey")
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("Error: \(error?.localizedDescription ?? "Unknown error")")
return
}
print(String(data: data, encoding: .utf8)!)
}

task.resume()

Kotlin (File Upload)

import okhttp3.*
import java.io.File

val client = OkHttpClient()
val apiKey = "YOUR_API_KEY"
val filePath = "/path/to/creditcard-statement.jpg"
val url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/file"

val file = File(filePath)
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.name, RequestBody.create(MediaType.parse("image/jpeg"), file))
.addFormDataPart("return_image", "false")
.addFormDataPart("return_ocr", "false")
.build()

val request = Request.Builder()
.url(url)
.post(requestBody)
.addHeader("apikey", apiKey)
.build()

client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}

override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) throw IOException("Unexpected code $response")
println(response.body()?.string())
}
}
})

Kotlin (Base64)

import okhttp3.*
import java.io.File
import android.util.Base64
import org.json.JSONObject

fun processBase64Image() {
val client = OkHttpClient()
val apiKey = "YOUR_API_KEY"
val filePath = "/path/to/creditcard-statement.jpg"
val url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/base64"

// Read file and convert to base64
val file = File(filePath)
val bytes = file.readBytes()
val base64String = Base64.encodeToString(bytes, Base64.DEFAULT)

val json = JSONObject()
json.put("base64_string", base64String)
json.put("return_image", false)
json.put("return_ocr", false)

val requestBody = RequestBody.create(
MediaType.parse("application/json"),
json.toString()
)

val request = Request.Builder()
.url(url)
.post(requestBody)
.addHeader("Content-Type", "application/json")
.addHeader("apikey", apiKey)
.build()

client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}

override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) throw IOException("Unexpected code $response")
println(response.body()?.string())
}
}
})
}

Java (File Upload)

import okhttp3.*;
import java.io.File;
import java.io.IOException;

public class Main {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();

String apiKey = "YOUR_API_KEY";
String url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/file";
String filePath = "/path/to/creditcard-statement.jpg";

File file = new File(filePath);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/jpeg"), file))
.addFormDataPart("return_image", "false")
.addFormDataPart("return_ocr", "false")
.build();

Request request = new Request.Builder()
.url(url)
.post(requestBody)
.addHeader("apikey", apiKey)
.build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
});
}
}

Java (Base64)

import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.nio.file.Files;
import org.json.JSONObject;

public class Main {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();

String apiKey = "YOUR_API_KEY";
String url = "https://api.iapp.co.th/ocr/v3/creditcard-statement/base64";
String filePath = "/path/to/creditcard-statement.jpg";

try {
// Read file and convert to base64
byte[] fileContent = Files.readAllBytes(new File(filePath).toPath());
String base64String = Base64.getEncoder().encodeToString(fileContent);

JSONObject json = new JSONObject();
json.put("base64_string", base64String);
json.put("return_image", false);
json.put("return_ocr", false);

RequestBody requestBody = RequestBody.create(
MediaType.parse("application/json"),
json.toString()
);

Request request = new Request.Builder()
.url(url)
.post(requestBody)
.addHeader("Content-Type", "application/json")
.addHeader("apikey", apiKey)
.build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}

Dart (File Upload)

import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;

String url = 'https://api.iapp.co.th/ocr/v3/creditcard-statement/file';
String filePath = '/path/to/creditcard-statement.jpg';
String apiKey = 'YOUR_API_KEY';

void main() async {
var url = Uri.parse(url);
var request = http.MultipartRequest('POST', url)
..headers['apikey'] = apiKey
..files.add(await http.MultipartFile.fromPath('file', filePath))
..fields['return_image'] = 'false'
..fields['return_ocr'] = 'false';

var response = await request.send();

if (response.statusCode == 200) {
var responseData = await response.stream.bytesToString();
print(responseData);
} else {
print('Error: ${response.statusCode}');
}
}

Dart (Base64)

import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;

String url = 'https://api.iapp.co.th/ocr/v3/creditcard-statement/base64';
String filePath = '/path/to/creditcard-statement.jpg';
String apiKey = 'YOUR_API_KEY';

void main() async {
var url = Uri.parse(url);
var request = http.MultipartRequest('POST', url)
..headers['apikey'] = apiKey
..files.add(await http.MultipartFile.fromPath('file', filePath))
..fields['return_image'] = 'false'
..fields['return_ocr'] = 'false';

var response = await request.send();

if (response.statusCode == 200) {
var responseData = await response.stream.bytesToString();
print(responseData);
} else {
print('Error: ${response.statusCode}');
}
}

Limitations & Best Practices

Limitations

  • Maximum file size: 10MB
  • Supported languages: Thai
  • PDF files: Up to 10 pages
  • Rate limit: 10 requests per second per API key

Best Practices

  1. Ensure good image quality for optimal results
  2. Use JPEG or PNG format for images
  3. Implement error handling for failed requests
  4. Cache responses when processing the same document multiple times
  5. Set appropriate timeouts for large files

Accuracy & Performance

Overall Accuracy

Based on our benchmark dataset of Thai credit card statements (over 1,000 Thai credit card statements documents):

Field TypeAccuracy (%)Notes
Card Numbers99.5%Masked for security
Amounts99.8%Currency values and totals
Dates99.0%Various Thai date formats
Transactions98.5%Description and amounts
Overall99.2%Weighted average

Processing Speed

  • Average processing time: 20-30 seconds
  • 95th percentile: 45 seconds
  • Maximum processing time: 60 seconds

Factors Affecting Accuracy

  1. Image Quality

    • Resolution (minimum 300 DPI recommended)
    • Lighting conditions
    • Image focus and clarity
  2. Document Condition

    • Physical damage
    • Fading or wear
    • Handwritten modifications
  3. Statement Format

    • Standard formats: 99%+ accuracy
    • Non-standard layouts: 95%+ accuracy
    • Handwritten elements: 90%+ accuracy

History

Our model is continuously trained on new data to improve accuracy:

VersionRelease DateAccuracyKey Improvements
3.02024-12-2799.2%Base version

Pricing

AI API Service NamePricingOn-Premise
Thai Credit Card Statement OCR1 IC/PageContact