Kyrim transfer API can enable your application to do money transfer from your account in Kyrim to beneficiary accounts like any bank accounts or wallets in Indonesia.
Kyrim partners with multiple banks and third parties to provide you reliable transfer capability that always available 24/7 with 99% success rate.
You can contact us and we will setup a call to help to get started with our API.
In general, what you need to do to transfer using Kyrim API are :
What you need to prepare to start integrating with Kyrim :
What Kyrim will give you to start integrating with Kyrim :
API Host :
Endpoint :
{{host}}/open-api/b2b/v1/access-token
You need to call this API to generate access token that you will need to call other API. This access token is one time use and expired in 15 minutes.
Headers
Name | Format | Mandatory | Description |
---|---|---|---|
Content-Type | application/json | Y | |
X-TIMESTAMP | YYYY-MM-DDTHH:MM:SS 2022-03-21T10:11:40+07:00 | Y | |
X-CLIENT-KEY | (from predefined variable) sample : cae55c3c-b862-4796-986f- ed20407d0883 | Y | |
X-SIGNATURE | algoritma asymmetric signature SHA256withRSA (Private_Key, stringToSign) stringToSign = client_ID + “ ” + X-TIMESTAMP | Y |
Sampe generate SHA256 with RSA using Golang
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"fmt"
"time"
)
const privateKeyPem = `-----BEGIN PRIVATE KEY-----
your_private_key_pkcs8_pem
-----END PRIVATE KEY-----`
const clientUuid = "your_client_id"
func main() {
// Format current time as ISO8601 without milliseconds
timestamp := time.Now().UTC().Format("2006-01-02T15:04:05Z")
// Create the string to sign
stringToSign := clientUuid + "|" + timestamp
// Decode the PEM formatted private key
block, _ := pem.Decode([]byte(privateKeyPem))
if block == nil {
fmt.Println("failed to parse PEM block containing the key")
return
}
// Parse the PKCS8 private key
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
fmt.Printf("failed to parse PKCS8 private key: %s\n", err)
return
}
rsaPrivateKey, ok := privateKey.(*rsa.PrivateKey)
if !ok {
fmt.Println("not an RSA private key")
return
}
// Calculate SHA256 hash
sha256Hash := sha256.New()
sha256Hash.Write([]byte(stringToSign))
hashed := sha256Hash.Sum(nil)
// Sign the SHA256 hash with RSA private key
signature, err := rsa.SignPKCS1v15(rand.Reader, rsaPrivateKey, crypto.SHA256, hashed)
if err != nil {
fmt.Printf("failed to sign: %s\n", err)
return
}
// Encode the signature to hexadecimal
signatureHex := hex.EncodeToString(signature)
// Output the signature
fmt.Println("Signature:", signatureHex)
}
Request
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
grant_type | String | 20 | Y | Value always "client_credentials" |
additional_info | Object | |||
- auth_id | String | 50 | Y | |
- auth_secret | String | 50 | Y |
Sample Request Body
{
"grant_type": "client_credentials",
"additional_info": {
"auth_id": "bf6696fe-01ae-469d-bbeb-xxxxxxxxx",
"auth_secret": "6b9c8067-84e6-48ce-b0f5-xxxxxxxxxx"
}
}
Response
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
response_code | String | 4 | Y | 20000 -> Succcess 40001 -> Incorrect Key |
response_message | String | 12 | Y | Success Incorrect Key |
access_token | String | 120 | Y | |
token_type | String | 6 | Y | Bearer |
expires_in | String | 3 | Y | 900 (unit in seconds) |
Sample Response Body
{
"response_code": "2000200",
"response_message": "Success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiI2YjljODA2Ny04NGU2LTQ4Y2UtYjBmNS1lYmJmNmJlNjQ5ZWMiLCJleHAiOjE3MjE3NDcxODYsInhfdGltZV9zdGFtcCI6IjIwMjQtMDctMjNUMjE6NTE6MjMuMDAwKzA3OjAwIn0.wZYZBtnYPLVRYL0IJKwwrlPVYqlT6TRIgGUqI6EQLfc",
"token_type": "Bearer",
"expires_in": "900"
}
}
{
"response_code": "4000200",
"response_message": "Bad request",
"data": null
}
Endpoint :
{{host}}/open-api/b2b/v1/account-inquiry
You need to call this endpoint before calling transfer API to validate if your transfer beneficiary is valid or not. You can input your bank code and account number, we will validate it and give the account name if the account you input is valid.
Headers
Name | Format | Mandatory | Description |
---|---|---|---|
Content-Type | application/json | Y | |
Authorization | Bearer {{access_ token}} | Y | |
X-TIMESTAMP | YYYY-MM-DDTHH:MM:SS sample : 2022-03-21T10:11:40+07:00 | Y | |
X-CLIENT-KEY | (from predefined variable) sample : cae55c3c-b862-4796-986f- ed20407d0883 | Y | |
X-SIGNATURE | HTTPMethod:EndpointUrl:Acce ssToken:EncodeRequestBody:Ti meStamp | Y | |
X-PARTNER-ID | KYR00013 | Y | |
X-EXTERNAL-ID | $unique_number_partner | Y | |
CHANNEL-ID | 01 | Y |
Request
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
bank_code | String | 4 | Y | List bank code [...] |
account_number | String | 12 | Y |
Sample Request Body
{
"account_number": "20240606001",
"bank_code": "013"
}
Response
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
response_code | String | 4 | Y | 20000 -> Succcess |
response_message | String | 12 | Y | Success |
bank_code | String | |||
bank_name | String | |||
account_number | String | |||
account_name | String | Account name from bank system. Use this to validate the beneficiary information. |
Sample Response Body
{
"response_code": "2000500",
"response_message": "Success",
"data": {
"bank_code": "013",
"bank_name": "Bank Permata UUS",
"account_number": "20240606001",
"account_name": "Jeremy BCA"
}
}
{
"response_code": "4040209",
"response_message": "Invalid account",
"data": null
}
Endpoint :
{{host}}/open-api/b2b/v1/transfer
This API do the money transfer from your balance in Kyrim account to the beneficiary account. Make sure, you already validate your account beneficiary with account inquiry API to make sure transfer valid.
Headers
Name | Format | Mandatory | Description |
---|---|---|---|
Content-Type | application/json | Y | |
Authorization | Bearer {{access_ token}} | Y | |
X-TIMESTAMP | YYYY-MM-DDTHH:MM:SS sample : 2022-03-21T10:11:40+07:00 | Y | |
X-CLIENT-KEY | (from predefined variable) sample : cae55c3c-b862-4796-986f- ed20407d0883 | Y | |
X-SIGNATURE | HTTPMethod:EndpointUrl:Acce ssToken:EncodeRequestBody:Ti meStamp | Y | |
X-PARTNER-ID | KYR00013 | Y | |
X-EXTERNAL-ID | $unique_number_partner | Y | |
CHANNEL-ID | 01 | Y |
Request
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
bank_code | String | 4 | Y | List bank code [...] |
account_number | String | 12 | Y | |
amount | Number | Y | Number between 10.0000 to 250.000.000 | |
description | String | |||
partner_reference_id | String | Y | Unique transaction id from your system. Can use uuid format. |
Sample Request Body
{
"account_number": "20240606005",
"amount": 10000,
"bank_code": "013",
"description": "cicilan",
"partner_reference_id": "2fe0eb09-0382-429a-8314-51f5792ade3b"
}
Response
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
response_code | String | 4 | Y | 20000 -> Succcess |
response_message | String | 12 | Y | Success |
Sample Response Body
{
"response_code": "2000500",
"response_message": "Success",
"data": {
"transfer_id": "b45e4892-b962-4ca2-921a-d4a8fbd539b0",
"bank_code": "013",
"bank_name": "Bank Permata UUS",
"account_number": "20240606001",
"account_name": "Jeremy BCA",
"amount": "10000",
"description": "cicilan",
"partner_reference_id": "2fe0eb09-0382-429a-8314-51f5792ade3b",
"email": "",
"transaction_date": "2024-07-24T12:03:15+07:00",
"status": "Submitted",
"transfer_fee": "100"
}
}
{
"response_code": "4000101",
"response_message": "Invalid field format. [Amount must be 10,000 or greater]",
"data": null
}
Endpoint :
{{host}}/open-api/b2b/v1/inquiry-transfer-status
You can get the latest status of transfer you have created before by calling this API.
Headers
Name | Format | Mandatory | Description |
---|---|---|---|
Content-Type | application/json | Y | |
Authorization | Bearer {{access_ token}} | Y | |
X-TIMESTAMP | YYYY-MM-DDTHH:MM:SS sample : 2022-03-21T10:11:40+07:00 | Y | |
X-CLIENT-KEY | (from predefined variable) sample : cae55c3c-b862-4796-986f- ed20407d0883 | Y | |
X-SIGNATURE | HTTPMethod:EndpointUrl:Acce ssToken:EncodeRequestBody:Ti meStamp | Y | |
X-PARTNER-ID | KYR00013 | Y | |
X-EXTERNAL-ID | $unique_number_partner | Y | |
CHANNEL-ID | 01 | Y |
Request
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
id | String | format uuid | Y | id: the ID given by our open API when it ran by the transfer endpoint. |
Sample Request Body
{
"id": "dd49de2e-4189-4b85-a903-xxxxxxxxx"
}
Response
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
response_code | String | 4 | Y | 20000 -> Succcess |
response_message | String | 12 | Y | Success |
id | String | |||
status | String | |||
bank_code | String | |||
amount | Number | |||
note | String |
Sample Response Body
{
"response_code": "2000500",
"response_message": "Success",
"data": {
"transfer_id": "8db43516-a265-4de7-a380-0ab034384bc3",
"bank_code": "028",
"bank_name": "Bank OCBC NISP",
"account_number": "20240606005",
"account_name": "JOHN BCA",
"amount": "10000",
"description": "angpau",
"partner_reference_id": "",
"email": "",
"transaction_date ": "2024-07-24T10:32:57+07:00",
"status ": "Diproses",
"transfer_fee ": "0"
}
}
{
"response_code": "4000101",
"response_message": "Invalid field format. [TransferID is a required field]",
"data": null
}
Endpoint :
{{host}}/open-api/b2b/v1/inquiry-balance
This endpoint used to get you balance in the Kyrim account.
Few scenario when you can use this endpoint:
Headers
Name | Format | Mandatory | Description |
---|---|---|---|
Content-Type | application/json | Y | |
Authorization | Bearer {{access_ token}} | Y | |
X-TIMESTAMP | YYYY-MM-DDTHH:MM:SS sample : 2022-03-21T10:11:40+07:00 | Y | |
X-CLIENT-KEY | (from predefined variable) sample : cae55c3c-b862-4796-986f- ed20407d0883 | Y | |
X-SIGNATURE | HTTPMethod:EndpointUrl:Acce ssToken:EncodeRequestBody:Ti meStamp | Y | |
X-PARTNER-ID | KYR00013 | Y | |
X-EXTERNAL-ID | $unique_number_partner | Y | |
CHANNEL-ID | 01 | Y |
Response
Field | Type | Length | Mandatory | Description |
---|---|---|---|---|
response_code | String | 4 | Y | 20000 -> Succcess |
response_message | String | 12 | Y | Success |
available_balance | Number | Balance that available to be used | ||
pending_balance | Number | Total balance that still on hold due to transaction processing | ||
time_request | Timestamp |
Sample Response Body
{
"response_code": "2000200",
"response_message": "Success",
"data": {
"available_balance": 9848800,
"pending_balance": 0,
"time_request": "2024-07-24T11:51:16+07:00"
}
}
{
"response_code": "5000200",
"response_message": "General error. Contact administrator for further information",
"data": null
}
You can do testing using this data below.
These are steps for you to get production access :
Check this link to see list of bank or account we cover in this transfer API.
Endpoint :
{{host}}/open-api/b2b/v1/health
You can call this endpoint to check if Kyrim server currently available or not.
Sample Response Body
{
"Status": "OK"
}
{
message: "Error"
}
Sahid Sudirman Center Level 23 Jl. Jend. Sudirman Kav 86 Karet Tengsin, Tanah Abang, Jakarta Pusat DKI Jakarta