Introduction

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 : 

  1. Use authentication API to get access token that will be used for other APIs. This token is one time use.
  2. Verify your transfer beneficiary (destination) by calling our account inquiry. This process meant to make sure you are transferring money to right destination.
  3. Transfer your money by calling transfer API. 
  4. Check the latest status of your transfer by calling check status API.
 
 Diagram below will help you understand how Kyrim API communicates with your applications.

What you need to prepare to start integrating with Kyrim : 

  • Public key. 
    Generate public-private key pair. Give the public to Kyrim. Kyrim will use this public key to verify signature data in the request body during API communication.

 

What Kyrim will give you to start integrating with Kyrim : 

  • Auth id and Auth secret
    You will need these data when calling authentication API to generate access token.

 

API Host : 

  • Sandbox
    https://kapi-stage.kyrim.im
  • Production
    https://kapi.kyrim.id

Authentication

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

NameFormatMandatoryDescription
Content-Typeapplication/jsonY
X-TIMESTAMPYYYY-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-SIGNATUREalgoritma 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

FieldTypeLengthMandatoryDescription
grant_typeString20YValue always "client_credentials"
additional_infoObject
- auth_idString50Y
- auth_secretString50Y

Sample Request Body

				
					{
    "grant_type": "client_credentials",
    "additional_info": {
        "auth_id": "bf6696fe-01ae-469d-bbeb-xxxxxxxxx",
        "auth_secret": "6b9c8067-84e6-48ce-b0f5-xxxxxxxxxx"
    }
}
				
			

Response

FieldTypeLengthMandatoryDescription
response_codeString4Y20000 -> Succcess
40001 -> Incorrect Key
response_messageString12YSuccess
Incorrect Key
access_tokenString120Y
token_typeString6YBearer
expires_inString3Y900 (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
}
				
			

Account Inquiry

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

NameFormatMandatoryDescription
Content-Typeapplication/jsonY
AuthorizationBearer {{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-SIGNATUREHTTPMethod:EndpointUrl:Acce
ssToken:EncodeRequestBody:Ti
meStamp
Y
X-PARTNER-IDKYR00013Y
X-EXTERNAL-ID$unique_number_partnerY
CHANNEL-ID01Y

Request

FieldTypeLengthMandatoryDescription
bank_codeString4YList bank code
[...]
account_numberString12Y

Sample Request Body

				
					{
    "account_number": "20240606001",
    "bank_code": "013"
}
				
			

Response

FieldTypeLengthMandatoryDescription
response_codeString4Y20000 -> Succcess
response_messageString12YSuccess
bank_codeString
bank_nameString
account_numberString
account_nameStringAccount 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
}
				
			

Transfer

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

NameFormatMandatoryDescription
Content-Typeapplication/jsonY
AuthorizationBearer {{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-SIGNATUREHTTPMethod:EndpointUrl:Acce
ssToken:EncodeRequestBody:Ti
meStamp
Y
X-PARTNER-IDKYR00013Y
X-EXTERNAL-ID$unique_number_partnerY
CHANNEL-ID01Y

Request

FieldTypeLengthMandatoryDescription
bank_codeString4YList bank code
[...]
account_numberString12Y
amountNumberYNumber between 10.0000 to 250.000.000
descriptionString
partner_reference_idStringYUnique 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

FieldTypeLengthMandatoryDescription
response_codeString4Y20000 -> Succcess
response_messageString12YSuccess

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
}
				
			

Inquiry Transfer Status

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

NameFormatMandatoryDescription
Content-Typeapplication/jsonY
AuthorizationBearer {{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-SIGNATUREHTTPMethod:EndpointUrl:Acce
ssToken:EncodeRequestBody:Ti
meStamp
Y
X-PARTNER-IDKYR00013Y
X-EXTERNAL-ID$unique_number_partnerY
CHANNEL-ID01Y

Request

FieldTypeLengthMandatoryDescription
idStringformat uuidYid: the ID given by our open API when it ran by the transfer endpoint.

Sample Request Body

				
					{
    "id": "dd49de2e-4189-4b85-a903-xxxxxxxxx"
}
				
			

Response

FieldTypeLengthMandatoryDescription
response_codeString4Y20000 -> Succcess
response_messageString12YSuccess
idString
statusString
bank_codeString
amountNumber
noteString

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
}
				
			

Inquiry Balance

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:

  1. Validate whether you have sufficient balance or not before making a transfer.
  2. Create monitor system to check if your balance in account goes below certain threshold, so you can prevent insufficient balance error case.

Headers

NameFormatMandatoryDescription
Content-Typeapplication/jsonY
AuthorizationBearer {{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-SIGNATUREHTTPMethod:EndpointUrl:Acce
ssToken:EncodeRequestBody:Ti
meStamp
Y
X-PARTNER-IDKYR00013Y
X-EXTERNAL-ID$unique_number_partnerY
CHANNEL-ID01Y

Response

FieldTypeLengthMandatoryDescription
response_codeString4Y20000 -> Succcess
response_messageString12YSuccess
available_balanceNumberBalance that available to be used
pending_balanceNumberTotal balance that still on hold due to transaction processing
time_requestTimestamp

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
}
				
			

Testing

You can do testing using this data below. 

 

Get Production Access

These are steps for you to get production access : 

  1. Do integration in our sandbox. Follow guides in this page to do integration from your app to Kyrim’s open API.
  2. KYB (Know Your Business) process. We will ask you to provide some documents, we will verify this documents to make you are eligible to do this partnership
  3. UAT meeting. We will give you UAT document to fill and schedule a meeting for you to demo the integration to our API.
  4. Production access granted. We will update your access to production access and give you new credentials to access production API.

Bank List

Check this link to see list of bank or account we cover in this transfer API.

Server Status

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

License

Certification

Register

Association

PT Kiriman Dana Pandai 2024. All rights reserved