NAV navbar
logo
responsebody

Merchant Integration Documentation

version v2
baseUri https://api.coowry.com/v2
protocols HTTPS

API Overview

The Coowry Transactional API is constructed as a RESTful service, and has been designed following these rules.

The API is resource oriented. Every resource offers a different view of the Coowry business data model. We rely on built-in HTTP features (authentication, verbs, etc.) that can be understood by off-the-shelf HTTP clients.

Request and Response Formats

         foo://example.com:8042/over/there?name=ferret#nose
         \_/   \______________/\_________/ \_________/ \__/
          |           |            |            |        |
       scheme     authority       path        query   fragment
          |   _____________________|__
         / \ /                        \
         urn:example:animal:ferret:nose

Source: http://tools.ietf.org/html/rfc3986

Monetary Values

All values must be in cents. If the currency does not have cents (eg. IDR), multiply the values by 100 before sending them to the API.

1.45 EUR -> 145
8 USD -> 800
10,000 IDR -> 1000000

Currencies

The Coowry API understands ISO 4217 currency codes.

Timestamps

Timestamps in Coowry are Unix timestamps, i.e. number of seconds between a particular date and the Unix Epoch (January 1st, 1970 at UTC).

MSISDNs

Phone numbers must follow standard MSISDN format, and be preceded by a +.

Authentication

Authentication is done via HTTP Basic Auth: Key and Secret.

All requests to the API must be done via HTTPS.

The Key authenticates the user and is used by the system to expose just the pieces of accesible information.

Timeouts

Calls to the /trades endpoints are advised to set a timeout of 30 seconds.

Versioning

Coowry uses Semantic Versioning in all its products. Versions follow the format X.Y.Z (X for major number, Y for minor number, and Z, for patch number). Bug fixes increment the patch version, backwards compatible changes increment the minor version, and backwards incompatible API changes increment the major version.

At this moment the major version operating is v2 and the current major version number can be found at https://api.coowry.com/v2.

API Errors

Error Object

{
  "status": <http status code>,
  "type": <error identifier>,
  "description": <human friendly description>,
  "arguments": <additional information>}
}

All errors returned by the Coowry API are JSON objects with the following fields

ParameterDescription
codeThe HTTP status code associated to this error
typeThe error type, unique to each error
descriptionHuman-friendly description of the error
argumentsAdditional information that completes the description

Coowry uses HTTP error codes to communicate the nature of the error. The errors returned by the API can be classified into three categories.

Your request is wrong (HTTP 400, 401, 403, 404).

You must check the request parameters and credentials before attempting another request.

Example Responses

HTTP/1.1 403 Forbidden
Content-Type: application/json
{
  "status": 403,
  "type": "forbidden",
  "description": "The request you made is not allowed",
  "arguments": {}}
}
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "status": 400,
  "type": "bad_request",
  "description": "Error in request parameters",
  "arguments": {
                 "non_valid":[],
                 "missing":["sender"],
                 "unexpected":[]
               }
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowed
404not_foundResource not found. Check the request URL

Coowry cannot perform the requested operation (HTTP 412).

These are errors unique to each process (payments, settlements, etc) and are to be expected during normal use of Coowry.

Example Responses

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "sender_unidentified",
  "description":"Sender not identified",
  "arguments": {}
}
codetypeDescription
412_Errors unique to each process (payments, settlements, etc)

Server Errors (HTTP 500, 503)

There was an unexpected error on Coowry's side (HTTP codes 500 and 503). Try again later, and contact us if problem persists.

Example Responses

HTTP/1.1 503 Service Unavailable
Content-Type: application/json
{
  "status": 503,
  "type": "service_unavailable",
  "description":"We are improving our systems",
  "arguments": {}
}
codetypeDescription
500_Internal server error. Try again later, and contact us if problem persists
503service_unavailableThe Coowry API is temporarily unavailable (most likely maintenance is underway)

Payments

Receiving payments through Coowry is a straightforward process: you order a payment and wait for the customer to confirm it.

Two different flows are available, depending on your ability to receive the payment outcome asynchronously.

We recommend you implement the asynchronous payments flow, as it provides a better user experience and a higher rate of completion.

Synchronous Payments

If you do not wish to implement asynchronous callbacks, the payment process consists of two synchronous calls to the API: one to create the trade and one to authorize it. In this case, the user will confirm by entering into your page a security code sent to his phone.

While this is flow provides a simpler integration, it has some limitations: the user must have enough balance in his Coowry account before starting the payment.

Asynchronous Payments

If you can accept the payment outcome asynchronously, the flow consists of one synchronous call to create the trade and an asynchronous callback from the API notifying the payment outcome.

Since authorization can be delayed, the user does not need to have enough balance in his account when starting the purchase. This provides more flexibility and a higher rate of completion.

The desired flow is selected by setting the field delayed when creating the payment.

Synchronous Payments

This flow eliminates the need to implement asynchronous callbacks. Two synchronous calls are made to the API:

  1. The customer enters his MSISDN into the checkout page.
  2. You make a call to the API requesting a payment.
  3. If the customer can be charged through Coowry, the API returns an HTTP 200 OK and sends a security code to the user.
  4. The user accepts the Terms of Service and enters the security code into your page.
  5. You make a call to the API with the security code authorizing the payment.
  6. The trade is authorized.

Synchronous payments flow

The payment will expire after 1 hour and it will fail if a wrong security code is entered more than three times.

A customer can only have one active payment at a time.

Requesting a payment

To charge a customer you must create a trade requesting airtime from him. This is equivalent to making a POST request to /trades.

Request

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/trades
Content-Type: application/json
{
        "sender": "+6212345678910",
        "receiver": "foo",
        "value": 500000,
        "currency": "IDR",
        "concept": "Subscription renewal",
        "reference": "REF-123456789",
}

The following fields must be specified in the body of the request:

ParameterDescriptionNotes
senderThe customer's MSISDNIn international format, eg. +34616839172 or +6212345678910
receiverYour API KeyProvided by Coowry
valueThe value to be charged to the customerValue must be in cents. For currencies that do not have cents (eg. IDR), multiply value by 100
currencyThe currency of said valueUse ISO 4217 currency codes
conceptThis will be seen by the customer, and should be informative as to what he is being charged for
referenceThis is for your use only. Use it to store any data relevant to your internal billing processeg. merchant's internal transaction ID

The body of the request must be encoded in application/json. The Content-Type header should be set accordingly.

Response: Success

If the user can be charged through Coowry, the API replies with an HTTP 200 OK and a JSON object that represents the created trade.

Example Response (Success)

HTTP/1.1 200 OK
Content-Type: application/json
{
        "id": "tr-la2js1mlrkrk",
        "status": "created",
        "sort": "p2b",
        "created": 1440231774,
        "operator_terms":
          {
            "version": "0.9",
            "url": "http://example.com",
            "operator": "Orange"
          }
}

Among other fields, the trade object contains the following,

ParameterDescriptionNotes
idCoowry's trade identification codeeg. tr-la2js1mlrkrk
statusStatus of this transactionWill remain created until payment is authorized by the customer
sortSort of the transactionFor payments to merchants, sort is always p2b (peer to business)
createdCreation timestampIn epoch time
operator_termsJSON object containing the operator's terms of serviceIf not null, the user must accept them before confirming the purchase

Changes in the status of the trade (when it is authorized or fails) will be notified through a callback to the URI you have specified. More info on how to do this can be found in Section Receiving a Result.

Response: Failure

In case of failure, an API error is returned. A payment request can fail for several reasons:

Example Response (Check request parameters)

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "status": 400,
  "type": "bad_request",
  "description": "Error in request parameters",
  "arguments": {
                 "non_valid":[],
                 "missing":["sender"],
                 "unexpected":[]
               }
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
400value_not_validThe value of the transaction is out of limits. Valid values range from 0.01 USD to 10 USD (look into field arguments for limits in local currency)
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowed
404not_foundResource not found. Check the request URL

Example Responses (Could not charge customer)

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "sender_unidentified",
  "description":"Sender not identified",
  "arguments": {}
}
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "net_not_active",
  "description":"Agent does not accept trades with the subscriber's network",
  "arguments": {
                 "opid": "op-00a6",
                 "operator": "Indosat"
               }
}
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "too_p2b_many_requests",
  "description": "Sender already has a pending purchase",
  "arguments": {
                 "open_requests": ["tr-6rc3alu7rqv6"]
               }
}
codetypeDescription
412sender_unidentifiedWe couldn't identify the customer's MSISDN. Make sure the MSISDN is correct. If problem persists, contact us
412sender_net_not_memberThe customer is a subscriber of a network which is not available through Coowry. Field arguments contains the mccmnc of the network
412sender_not_enough_balanceThe customer does not have enough balance in his Coowry account to complete this paymentCoowry will give instructions to the customer to charge his account
412net_not_activeThe merchant does not accept payments from subscribers of this network. Field arguments contains the name and id of the network. If you want to activate or deactivate payments for certain networks, contact us
412too_many_p2b_requestsCustomer already has a pending purchase. Authorize it or cancel it before attempting a new one. The trade id is returned in arguments
412sender_blacklistedThe customer is a suspect of fraudulent activity, and has been temporarily blacklisted

Authorizing the payment

After you succesfully request a payment from a user, Coowry will send a security code to the user via SMS. You must present the user with a form to enter this code (usually a 4-digit token) and the terms of service. Once the user enters the token, you must send it to the API to authorize the trade and complete the payment.

You must present the user with the terms of service. More info on how to do this here.

Request

The trade is authorized by making a POST to https://api.coowry.com/v2/trades/:trid/authorization where trid is the trade id returned after requesting the payment.

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/trades/tr-la2js1mlrkrk/authorization
Content-Type: application/json
{
        "auth_token": "1234"
}

The following fields must be specified in the body of the request:

ParameterDescriptionNotes
auth_tokenAuthorization token4-digit security code entered by your customer

The body of the request must be encoded in application/json. The Content-Type header should be set accordingly.

Response: Success

If the security code was correct and the user has enough balance, the trade is authorized.

Example Response (Success)

HTTP/1.1 200 OK
Content-Type: application/json
{
        "id": "tr-la2js1mlrkrk",
        "status": "authorized",
        "sort": "p2b",
        "created": 1440231774

}

The API returns a JSON object containing the authorized trade.

ParameterDescriptionNotes
idCoowry's trade identification codeeg. tr-la2js1mlrkrk
statusStatus of this transactionValue will be authorized
sortSort of the transactionFor payments to merchants, sort is always p2b (peer to business)
createdCreation timestampIn epoch time

Response: Failure

In case of failure, an API error is returned. An attempt to authorize the trade can fail for several reasons,

Example Response (Check request parameters)

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "status": 400,
  "type": "bad_request",
  "description": "Error in request parameters",
  "arguments": {
                 "non_valid":[],
                 "missing":["sender"],
                 "unexpected":[]
               }
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowedRemember that trades ordered with delayed=true do not admit authorization by token
404not_foundResource not found. Check the request URL

Example Responses

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "wrong_token",
  "description":"Wrong token",
  "arguments": {
                 "tries_left": 2
               }
}
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "wrong_status",
  "description":"Trade is in the wrong status",
  "arguments": {
                 "status": "authorized"
               }
}
codetypeDescription
412sender_not_enough_balanceThe customer does not have enough balance in his Coowry account to complete this paymentCoowry will give instructions to the customer to charge his account
412wrong_tokenThe authorization token is wrongField arguments contains the number of remaining attempts
412too_many_auth_attemptsToken was wrong and the maximum number of authorization attemtps has been reached. The trade is failed
412wrong_statusThe trade has already been authorized or has failed

Cancelling a payment

A payment can be cancelled before it is authorized. This is a convenient feature and you should give the customer the possibility to cancel the payment.

Request

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/trades/tr-la2js1mlrkrk/cancellation
Content-Type: application/json
{}

The trade is cancelled by making a POST request to https://api.coowry.com/v2/trades/:trid/cancellation, where trid is the trade id returned after requesting the payment.

The body of the request must be left empty and be encoded in application/json. The Content-Type header should be set accordingly.

Response: Success

The API returns a JSON object containing the cancelled trade.

Example Response (Success)

HTTP/1.1 200 OK
Content-Type: application/json
{
        "id": "tr-la2js1mlrkrk",
        "status": "failed",
        "sort": "p2b",
        "created": 1440231774

}
ParameterDescriptionNotes
idCoowry's trade identification codeeg. tr-la2js1mlrkrk
statusStatus of this transactionValue will be failed after cancellation
sortSort of the transactionFor payments to merchants, sort is always p2b (peer to business)
createdCreation timestampIn epoch time

Response: Failure

In case of failure, an API error is returned. An attempt to cancel a trade can fail for several reasons.

Example Response (Check request parameters)

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "status": 401,
  "type":" not_authorized",
  "description": "Unauthorized",
  "arguments": {}
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowedThis probably means the trid you specified references a different trade
404not_foundResource not found. Check the request URL

Example Responses

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "wrong_status",
  "description":"Trade is in the wrong status",
  "arguments": {
                 "status": "authorized"
               }
}
codetypeDescription
412wrong_statusThe trade has already been authorized or has failed

Resending the authorization SMS

You can force the resend of an authorization SMS, which contains the security code to authorize a trade. This is useful in cases when the SMS is not delivered or the customer can’t find it.

The authorization SMS can be resent a maximum of three times. Please note that the the security code changes every time the SMS is resent.

Request

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/trades/tr-la2js1mlrkrk/tokens
Content-Type: application/json
{}

The authorization SMS is resent by making a POST request to https://api.coowry.com/v2/trades/:trid/tokens, where trid is the trade id returned after requesting the payment.

The body of the request must be left empty and be encoded in application/json. The Content-Type header should be set accordingly.

Response: Success

The API returns an HTTP 204 No Content and an empty body.

Example Response (Success)

HTTP/1.1 204 No Content
Content-Type: application/json
{}

Response: Failure

In case of failure, an API error is returned. An attempt to resend the authorization SMS can fail for several reasons.

Example Response (Check request parameters)

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "status": 401,
  "type":" not_authorized",
  "description": "Unauthorized",
  "arguments": {}
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowedRemember that trades ordered with delayed=true do not admit authorization by token
404not_foundResource not found. Check the request URL

Example Responses

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "wrong_status",
  "description":"Trade is in the wrong status",
  "arguments": {
                 "status": "authorized"
               }
}
codetypeDescription
412wrong_statusThe trade has already been authorized or has failed

Terms of Service

Only Coowry's Terms of Service

By authorizing the payment you are accepting Coowry's Terms of Service

"operator_terms": null

With Operator's Terms of Service

By authorizing the payment you are accepting Coowry's Terms of Service and Indosat's Terms of Service

"operator_terms":
  {
    "url": "http://example.com",
    "operator": "Indosat",
    "version": "1.2"
  }

Before authorizing the payment, the user must accept Coowry's Terms of Service and, if necessary, its operator's Terms of Service.

The acceptance can be implicit, ie. the user accepts the terms by entering the security code and authorizing the payment. The wording must be something similar to (in the local language),

By authorizing the payment you are accepting Coowry's Terms of Service

or, if the operator's Terms of Service are present,

By authorizing the payment you are accepting Coowry's Terms of Service and Indosat's Terms of Service

The URL to Coowry's Terms of Service is https://www.coowry.com/terms.

The URL to the operator's Terms of Service is can be found inside the field operator_terms returned when requesting a payment.

If this field is null, the user only needs to accept Coowry's terms of service. If not, this field is a JSON object with the following fields,

Asynchronous Payments

This uses one synchronous call to the API to order the payment and a callback to receive the outcome,

  1. The customer enters his MSISDN into the checkout page.
  2. You make a call to the API requesting a payment.
  3. If the customer can be charged through Coowry, the API returns an HTTP 200 OK.
  4. The user follows instructions sent to his mobile to complete the trade.
  5. You receive a callback from the Coowry API with the payment outcome (either authorized or failed).

Asynchronous payment flow

The payment will expire after 1 hour and a customer can only have one active payment at a time. You will be notified through the callback when the payment expires.

Requesting a payment asynchronously

To charge a customer you must create a trade requesting airtime from him. This is equivalent to making a POST request to /trades.

Request

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/trades
Content-Type: application/json
{
        "sender": "+6212345678910",
        "receiver": "foo",
        "value": 500000,
        "currency": "IDR",
        "concept": "Subscription renewal",
        "reference": "REF-123456789",
}

The following fields must be specified in the body of the request:

ParameterDescriptionNotes
senderThe customer's MSISDNIn international format, eg. +34616839172 or +6212345678910
receiverYour API KeyProvided by Coowry
valueThe value to be charged to the customerValue must be in cents. For currencies that do not have cents (eg. IDR), multiply value by 100
currencyThe currency of said valueUse ISO 4217 currency codes
conceptThis will be seen by the customer, and should be informative as to what he is being charged for
referenceThis is for your use only. Use it to store any data relevant to your internal billing processeg. merchant's internal transaction ID
delayedMust be set to true to indicate that you will be notified of the payment outcome via callbackSetting your Callback URI

The body of the request must be encoded in application/json. The Content-Type header should be set accordingly.

Response: Success

If the user can be charged through Coowry, the API replies with an HTTP 200 OK and a JSON object that represents the created trade.

Example Response (Success)

HTTP/1.1 200 OK
Content-Type: application/json
{
        "id": "tr-la2js1mlrkrk",
        "status": "created",
        "sort": "p2b",
        "created": 1440231774

}

Among other fields, the trade object contains the following,

ParameterDescriptionNotes
idCoowry's trade identification codeeg. tr-la2js1mlrkrk
statusStatus of this transactionWill remain created until payment is authorized by the customer
sortSort of the transactionFor payments to merchants, sort is always p2b (peer to business)
createdCreation timestampIn epoch time

The customer must now authorize the purchase. Changes in the status of the trade (when it is authorized or fails) will be notified through a callback to the URI you have specified. More info on how to do this can be found in section Receiving a Result.

Response: Failure

In case of failure, an API error is returned. A payment request can fail for several reasons:

Example Response (Check request parameters)

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "status": 400,
  "type": "bad_request",
  "description": "Error in request parameters",
  "arguments": {
                 "non_valid":[],
                 "missing":["sender"],
                 "unexpected":[]
               }
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
400value_not_validThe value of the transaction is out of limits. Valid values range from 0.01 USD to 10 USD (look into field arguments for limits in local currency)
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowed
404not_foundResource not found. Check the request URL

Example Responses (Could not charge customer)

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "sender_unidentified",
  "description":"Sender not identified",
  "arguments": {}
}
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "net_not_active",
  "description":"Agent does not accept trades with the subscriber's network",
  "arguments": {
                 "opid": "op-00a6",
                 "operator": "Indosat"
               }
}
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "too_p2b_many_requests",
  "description": "Sender already has a pending purchase",
  "arguments": {
                 "open_requests": ["tr-6rc3alu7rqv6"]
               }
}
codetypeDescription
412sender_unidentifiedWe couldn't identify the customer's MSISDN. Make sure the MSISDN is correct. If problem persists, contact us
412sender_net_not_memberThe customer is a subscriber of a network which is not available through Coowry. Field arguments contains the mccmnc of the network
412callback_not_definedYou ordered the trade with delayed=true but you haven't set a notification callback.
412net_not_activeThe merchant does not accept payments from subscribers of this network. Field arguments contains the name and id of the network. If you want to activate or deactivate payments for certain networks, contact us
412too_many_p2b_requestsCustomer already has a pending purchase. Authorize it or cancel it before attempting a new one. The trade id is returned in arguments
412sender_not_enough_balanceThe customer does not have enough balance in his Coowry account to complete this paymentCoowry will give instructions to the customer to charge his account
412sender_blacklistedThe customer is a suspect of fraudulent activity, and has been temporarily blacklisted

Receiving the result

Coowry will make callbacks to an URI of your choice when a payment you have requested is authorized by the customer or it fails. A POST request will be made to the URI that you have specified, informing you of the event.

Callback example

You will receive the following request at your callback URI

HTTP/1.1 POST
Content-Type: application/json
{
  "event": "trade_status_changed",
  "signature": "35cf63b570443c32f4df2d3179c81e003ff5e62e",
  "payload": {
               "trid": "tr-la2js1mlrkrk",
               "reference": "REF-123456789",
               "status": "authorized"
             }
}

The body of this request is a JSON object with the following fields,

ParameterDescriptionNotes
eventThe event that triggered this callbackIn this case, trade_status_changed
payloadThe payload of the callbackIn this case, information on the trade that was authorized or failed
signatureSignature used to verify that the call originated from Coowry's serversMore info on how to calculate the signature, see Section Calculating the Signature

In this case, the payload will be a JSON object with the following fields,

ParameterDescriptionNotes
tridCoowry's trade identification codeeg. tr-la2js1mlrkrk
referenceMerchant transaction Id.This will be the same as the field reference you provided during the payment request
statusStatus of the paymentFor callbacks this will always be authorized or failed

Your server must reply with HTTP status codes 200 OK or 204 No Content.

Your reply should be one of the following

HTTP/1.1 200 OK
EMPTY BODY

HTTP/1.1 204 No Content
EMPTY BODY

If the response is something else, Coowry will reattempt the callback three times. If still unsucesfull, you will by notified by another channel (eg. an email from the Coowry team).

Calculating the signature

The signature is calculated by combining the callback secret and the fields of the payload. A new callback secret is generated every time you set a new callback URI.

Calculating the signature

APPEND THE FIELDS IN ALPHABETICAL ORDER (field=value)

  reference=REF-123456789 ++ status=authorized ++ trid=tr-la2js1mlrkrk

ADD SECRET AT THE END

  reference=REF-123456789status=authorizedtrid=tr-la2js1mlrkrk ++ av56cxsa1fyrbtc5

PERFORM SHA1 DIGEST

  sha1 ( reference=REF-123456789status=authorizedtrid=tr-la2js1mlrkrkav56cxsa1fyrbtc5 ) = 35cf63b570443c32f4df2d3179c81e003ff5e62e

The signature is calculated by combining the callback secret and the fields of the payload. A new callback secret is generated every time you set a new callback URI.

To calculate the signature,

For example, the signature for the callback on the left was calculated by running a SHA1 digest over the following string:

reference=REF-123456789status=authorizedtrid=tr-la2js1mlrkrkav56cxsa1fyrbtc5

where av56cxsa1fyrbtc5 is the callback secret.

Setting your callback URI

You are responsible for setting your callback URI. This means you can change it anytime.

Everytime the callback URI is set, a new callback secret will be generated. You can always reset the callback if you feel the secret has been compromised.

Request

To set or change your callback URI, you must make a POST request to /agents/foo/callbacks, where foo is your agent API Key.

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/agents/foo/callbacks
Content-Type: application/json
{
  "callback_uri": "https://mycompany.com/callbacks"
}

Only one parameter must be encoded in the request body,

ParameterDescriptionNotes
callback_uriThe callback URIProtocol must be included, ie. https://mycompany.com/callbacks instead of mycompany.com/callbacks. Only https is available at the moment.

The body of the request must be encoded in application/json. The Content-Type header should be set accordingly.

Response

Example Response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "callback_uri": "https://mycompany.com/callbacks",
  "callback_secret": "mwwzx6cuu5hjjpiv"
}

The Coowry API will return a JSON object with two fields:

ParameterDescription
callback_uriSame as provided in the request
callback_secretThe secret that will be used to calculate the signature for callbacks and verify that the request originated in the Coowry API

You can renew the secret at any time by repeating the previous request.

Testing your callback

Once you set a new callback, you can test it by making a POST request to /agents/foo/callbacks/test, where foo is your agent API Key. The body must be defined but left empty.

This will trigger a callback to the URI that you have defined, with a dummy object.

Cancelling a payment

Asynchronous payments can also be cancelled before they are authorized. The behaviour is the same as in synchronous payments, as described in Cancelling a Payment.

Settlements

Making a settlement

To make a settlement you must create a trade sending airtime to the customer.

This is equivalent to making a POST request to /trades.

Request

Example Request

HTTP/1.1 POST https://api.coowry.com/v2/trades
Content-Type: application/json
{
        "sender": "foo",
        "receiver": "+6212345678910",
        "value": 500000,
        "currency": "IDR",
        "concept": "Monthly settlement",
        "reference": "REF-123456789",

}

The following fields must be specified in the body of the request:

ParameterDescriptionNotes
senderYour API KeyProvided by Coowry
receiverThe customer's MSISDNIn international format, eg. +34616839172 or +6212345678910
valueThe value to be sent to the customerValue must be in cents. For currencies that do not have cents (eg. IDR), multiply value by 100
currencyThe currency of said valueUse ISO 4217 currency codes
conceptThis will be seen by the customer, and should be informative
referenceThis is for your use only. Use it to store any data relevant to your internal settlement processeg. merchant's internal transaction ID

The body of the request must be encoded in application/json. The Content-Type header should be set accordingly.

Response: Success

The API responds with an HTTP 200 OK and the airtime has been transfered to your customer. The trade's status is authorized and the settlement is complete.

Example Response (Success)

HTTP/1.1 200 OK
Content-Type: application/json
{
        "id": "tr-la2js1mlrkrk",
        "status": "authorized",
        "sort": "b2p",
        "created": 1440231774

}

The API returns a JSON object with the following fields (besides the ones you defined in the request).

ParameterDescriptionNotes
idCoowry's trade identification codeeg. tr-la2js1mlrkrk
statusStatus of this transactionAlways authorized for settlements if the request was made through the API
sortSort of the transactionFor settlements, sort is always b2p (business to people)
createdCreation timestampIn epoch time

Response: Failure

In case of failure, an API error is returned. A settlement request can fail for several reasons:

Example Response (Check request parameters)

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "status": 400,
  "type": "bad_request",
  "description": "Error in request parameters",
  "arguments": {
                 "non_valid":[],
                 "missing":["sender"],
                 "unexpected":[]
               }
}
codetypeDescription
400malformed_requestThere is a problem with the parameters in your request. Look into fields description and arguments for more details.
400value_not_validThe value of the transaction is out of limits. Valid values range from 0.01 USD to 10 USD (look into field arguments for limits in local currency)
401not_authorizedYour credentials are wrong
403forbiddenThe request you made is not allowed
404not_foundResource not found. Check the request URL

Example Error Responses

HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
  "status": 412,
  "type": "sender_unidentified",
  "description":"Sender not identified",
  "arguments": {}
}
codetypeDescription
412receiver_unidentifiedWe couldn't identify the customer's MSISDN. Make sure the MSISDN is correct. If problem persists, contact us
412receiver_net_not_memberThe customer is a subscriber of a network which is not available through Coowry. Field arguments contains the mccmnc of the network
412sender_not_enough_balanceYou don't have enough airtime in your Coowry account for the subscriber's network. Contact us for more information