CM payments offers a solution for online and mobile payment transactions. The system supports several payment methods eg iDEAL, iDEAL QR, Credit Cards, Afterpay and Bancontact.
The URL to be used is: https://api.cmpayments.com
Charge | A Charge is always an incoming payment |
---|---|
Payment | The payment coupled to a charge |
Payment details | Describes the payment method details |
In the documentation we will describe the following entities:
Charge: A Charge is a container that holds the total owed amount that should be paid by an end-user. When creating a Charge, we always create a Payment as well. A Charge and Payment have one-to-one relationship. In this document we’ll deal with: creating a single Charge and retrieving a single Charge.
Payment: A Payment describes a single payment from an end-user to a Merchant. For now, a Charge has one-to-one relationship with Payment. In the future it will be possible for a single Charge to have 0, n Payments (one-to-many).*
In this document we’ll deal with; creating a single Payment, retrieving a single Payment
Payment details: As each payment method requires specific details to accompany the generic payment data in order to fulfill a payment successfully the payment details are defined as flexible mean to pass these details to the payment method. One payment can have 0 to n Payment details (zero-to-many).
For now, it is not possible to create a single Charge and later on link a single Payment to this Charge. In this version the relationship between a Charge and a Payment is one-to-one. When you create a Charge, a single Payment will also be created in the process. Both Charge and Payment will be returned in the Response when creating a Charge.
Status notifications. When the status of a Payment or Charge changes the API will send a callback. With this callback we can make sure CM Payments and the merchant will be kept up to date when the status of a Payment changes.
Authentication. Some calls on the API require OAuth version 1.0, we use this protocol to ensure safety for our customers. More on implementing the OAuth protocol can be read in When we send a callback we check your http status code. We consider a status code of 200 a valid status code. If we cannot reach the backend URL you supplied the Request will be queued to be retried at a later time.
It’s very important to as the merchant to make sure that if everything is working as it should be to return a 200 http status code. This way we will not have to retry the callback.
Version | Author | Date | Status |
---|---|---|---|
1.0.0 | CM | 08-04-2016 | Initial version |
1.1.0 | CM | 15-04-2016 | Added AfterPay |
1.2.0 | BW | 02-05-2016 | Updated OAuth documentation |
1.3.0 | CM | 03-05-2016 | Updated AfterPay request / response parameters |
1.4.0 | BW | 06-05-2016 | Updated Payment Request Capture property |
1.4.1 | BW | 10-05-2016 | Typo |
1.5.0 | BW | 10-05-2016 | Issuers URL |
1.6.0 | BW | 10-05-2016 | Introduced Payment test property |
1.7.0 | BW | 09-06-2016 | Updated Issuers response; added different response for Merchant in Test modus |
1.8.0 | KK | 10-06-2016 | Afterpay refund, afterpay result in JSON body |
1.9.0 | KK | 13-06-2016 | Added SIPS request and response |
1.9.1 | KK | 15-07-2016 | SIPS to Creditcard and Bancontact |
1.12.0 | KK | 03-10-2016 | Sofort, Paypal and iDeal refunds |
1.13.0 | MW | 15-07-2016 | Adding Wire Transfer |
1.13.1 | MSC | 15-07-2016 | Restructure |
1.13.2 | MW | 15-07-2016 | dd extra URL-possibilities in iDEAL QR |
1.13.2a | MSC | 07-4-2017 | Added .NET SDK |
1.14.0 | JG | 07-12-2018 | Document DirectDebit Reversal status; document Refund statusses |
1.14.1 | JG | 14-12-2018 | Moved SDK details to their own (external) pages |
Every request send to our API needs to be signed. For authentication we are using OAuth 1.0a protocol.
Note: all variables mentioned in this chapter are fictional and for demo purposes only.
If the .NET SDK is used, requests are authenticated automatically.
When using PHP and Guzzle, a middleware that handles authentication is available.
All of our APIs are based on the HTTP protocol. Any HTTP library should be able to generate and issue the above request with a minimum of difficulty. To allow applications to provide this information, our API relies on the OAuth 1.0a protocol
You should be able to see that the header contains 6 key/value pairs, where the keys all begin with the string 'oauth_'. For any given API request, collecting these 6 values and creating a similar header will allow you to specify authorisation for the request. How each value was generated is described below:
Consumer Key The ‘oauth_consumer_key’ identifies which application is making the request. You'll be provided with such a key.
oauth_consumer_key | /xvz1evFS4wEEPTGEFPHBog |
oauth_consumer_key
Nonce
The 'oauth_nonce' parameter is a unique token your application should generate for each unique request. We will use this value to determine whether a request has been submitted multiple times. The value for this request was generated by base64 encoding 32 bytes of random data, and stripping out all non-word characters, but any approach which produces a relatively random alphanumeric string should be OK here.
oauth_nonce | /32f3c8c2b06e96ec8e19eb4d39672720 |
oauth_nonce
Signature
The 'oauth_signature' parameter contains a value which is generated by running all of the other request parameters and two secret values through a signing algorithm. The purpose of the signature is so that we can verify that the request has not been modified in transit, verify the application sending the request, and verify that the application has authorisation to interact with the user’s account. This will be explained in Creating a signature.
oauth_signature | /N2U4YzAyYmZjMDkyZTE3NGVmMjYyNmYzZDQ0ZTM0NGMwZmJkNjgzMmI |
3NWRjMDQ2MDUxOTAwMjQ2MGU0Y2VlZg== | |
Signature method The 'oauth_signature_method' used is HMAC-SHA256. This value must be used for any authorised request sent to our API.
oauth_signature | /HMAC-SHA256 |
Timestamp The 'oauth_timestamp' parameter indicates when the request was created. This value should be the number of seconds since the Unix epoch at the point the request is generated, and should be easily generated in most programming languages. We will reject requests which were created too far in the past, so it is important to keep the clock of the computer generating requests in sync with NTP.
oauth_timestamp 1443539180
Version The 'oauth_version' parameter should always be 1.0 for any request sent to our API.
oauth_version 1.0
To build the header string, imagine writing to a string named DST.
For each key/value pair of the 6 parameters listed in Collecting parameters:
a. URL encode the key and append it to DST.
b. Append the equals character '=' to DST.
c. Append a double quote '“' to DST.
d. URL encode the value and append it to DST.
e. Append a double quote '“ ' to DST.
f. If there are key/value pairs remaining, append a comma ',' and a space ' ' to DST.
Pay particular attention to the percent encoding of the values when building this string. For example, the ‘oauth_signature’ value of
N2U4YzAyYmZjMDkyZTE3NGVmMjYyNmYzZDQ0ZTM0NGMwZmJkNjgzMmI3NWRjMDQ2MDUxOTAwMjQ2MGU0Y2VlZg==
must be URL encoded as
N2U4YzAyYmZjMDkyZTE3NGVmMjYyNmYzZDQ0ZTM0NGMwZmJkNjgzMmI3NWRjMDQ2MDUxOTAwMjQ2MGU0Y2VlZg%3D%3D Performing these steps on the parameters collected above results in the following string:
OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog", oauth_nonce="32f3c8c2b06e96ec8e19eb4d39672720", oauth_signature="N2U4YzAyYmZjMDkyZTE3NGVmMjYyNmYzZDQ0ZTM0NGMwZmJkNjgzMmI3NWRjMDQ2MDUxOTAwMjQ2MGU0Y2VlZg%3D%3D", oauth_signature_method="HMAC-SHA256", oauth_timestamp="1443539180", oauth_version="1.0"
This value should be set as the 'Authorization' header for the request.
Encoding can be best done in PHP with 'rawurlencode'.
function createRequestSignature(string $consumerKey, string $consumerSecret, string $targetUrl, string $httpMethod, string $body = null): string { // vars needed for signature string creation $signatureKeys = [ 'oauth_consumer_key', 'oauth_nonce', 'oauth_signature_method', 'oauth_timestamp', 'oauth_version' ]; // vars needed for header string creation $headerKeys = [ 'oauth_consumer_key', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method', 'oauth_timestamp', 'oauth_version' ]; // set vars needed $vars = array_flip($signatureKeys); $vars['oauth_nonce'] = md5(uniqid(microtime(true), true)); $vars['oauth_signature_method'] = 'HMAC-SHA256'; $vars['oauth_timestamp'] = time(); $vars['oauth_version'] = '1.0'; // Oauth credentails $vars['oauth_consumer_key'] = $consumerKey; /** * Create Signature */ $signature = array_intersect_key($vars, array_flip($signatureKeys)); // query parameters parse_str(parse_url($targetUrl, PHP_URL_QUERY), $params); $signature += $params; ksort($signature); // start collecting the signature parts $signatureParts = [rawurlencode($body)]; foreach ($signature as $signatureKey => $signatureValue) { $signatureParts[] = rawurlencode($signatureKey . '=' . $signatureValue); } // remove any empty values and implode the $signatureParts array $signatureString = implode(rawurlencode('&'), array_filter($signatureParts)); // start collecting the signature base parts $signatureBaseParts = [ $httpMethod, rawurlencode($targetUrl), $signatureString ]; // remove any empty values and implode the $signatureBaseParts array $signatureBaseString = implode('&', array_filter($signatureBaseParts)); // create the signing key $signingKey = rawurlencode($consumerKey) . '&' . rawurlencode($consumerSecret); // calculate signature $vars['oauth_signature'] = base64_encode(hash_hmac('sha256', $signatureBaseString, $signingKey)); /** * Create header string */ $headerParts = array_intersect_key($vars, array_flip($headerKeys)); ksort($headerParts); // get the last key; $lastKey = key(array_reverse($headerParts)); // start building header string $headerString = ''; foreach ($headerParts as $headerKey => $headerValue) { $headerString .= rawurlencode($headerKey) . '="' . rawurlencode($headerValue) . '"'; if ($headerKey !== $lastKey) { $headerString .= ', '; } } return $headerString; } // Sample request body - see chapter 2.1 for details $requestBody = '{ "amount": 12.95, "currency": "EUR", "payments": [ { "amount": 12.95, "currency": "EUR", "payment_method": "iDEAL", "payment_details": { "issuer_id": "INGBNL2A", "purchase_id": "GX32AAA", "description": "Dit is een test description" } } ] }'; // Generate the signature $signature = createRequestSignature("YOUR_MERCHANT_KEY", "YOUR_CONSUMER_SECRET", "https://api.cmpayments.com/charges/v1", "POST", $requestBody); // Use the signature in the request headers $requestHeaders[] = 'Authorization: OAuth ' . $signature;
This chapter gives an overall overview of all the general parameters which apply to all payment methods. The chapters hereafter will describe the specific information per payment payment method.
Create a single Charge by calling the following URL via the HTTP-POST method.
POST | /charges/v1 |
Every request consists of two objects. A charge object and a payment object. The following parameters apply for all payment methods:
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
amount | Decimal | 19,2 | Yes | Amount of the payment, with a maximum precision of 4 (e.g. 0.12). The dot (.) is considered the decimal separator and is not mandatory and may only be used once. Minumum amount for Bancontact is 0.02. For other payment methods 0.01. |
currency | String | 3 | Yes | Currency code in ISO-4217 format. |
payments | Array | 1 | Yes | Contains more information about the Payment connected to the Charge. |
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
amount | Decimal | 19,2 | Yes | Amount of the payment, with a maximum precision of 2 (e.g. 0.12). The dot (.) is considered the decimal separator and is not mandatory and may only be used once. Minumum amount for Bancontact is 0.02. For other payment methods it is 0.01. |
currency | String | 3 | Yes | Currency code in ISO-4217 format. |
payment_method | String | 30 | Yes | Payment method used to make the payment.Available payment methods are: iDEAL, AfterPay, Creditcard and Bancontact. |
due_date | DateTime UTC | - | No | Date of expiration for the payment. |
payment_details | Object | - | Yes | Contains more in depth information about the Payment. Depending on the chosen payment method, different payment_details properties are mandatory. Read 3.4 for more details. |
expires_at | DateTime UTC | - | Only for Wire Transfer | The latest date that the consumer may pay the payment. If not provided, a period of 7 days will be used. |
In the response upon creation of a Charge the Charge and Payment object will maintain the same format. Per paymentmethod different Payment Details may be present.
Name | Format | Length | Description |
---|---|---|---|
charge_id | String | 39 | Unique ID of the charge. |
status | String | 9 | Status of the charge. A status can be: Open, Expired, Failed, Reversed, Success, Accepted, Refunded, RefundPending, RefundFailed or Cancelled. |
amount | Decimal | 19,2 | The amount for the charge. |
currency | String | 3 | Currency used for the charge in ISO-4217 format. |
created_at | DateTime UTC | - | Creation date of the charge |
updated_at | DateTime UTC | - | Update date of the charge. |
Specific charge method object response parameters are described with the payment method.
Name | Format | Length | Description |
---|---|---|---|
payment_id | String | 39 | Id of the payment object. |
payment_method | String | 30 | Payment method used to make the payment. Available payment methods are: iDEAL, AfterPay. |
charge_id | String | 39 | Charge id linked to the payment object. |
status | String | 9 | Status of the Payment. A status can be: Open, Expired, Failed, Reversed, Success, Accepted, Refunded, RefundPending, RefundFailed or Cancelled. |
amount | Decimal | 19,2 | Amount of the payment. |
currency | String | 3 | Currency of the payment in ISO-4217 format. |
due_date | DateTime UTC | - | Expiration date of the payment. |
test | Boolean | - | Indication of Payment was created in test modus. Test mode is dependent on Merchant’ test setting |
created_at | DateTime UTC | - | Creation date of the payment. |
updated_at | DateTime UTC | - | Update date of the payment. |
expires_at | DateTime UTC | - | Only for the paymentmethod Wire Transfer. The maximum date of paying this transaction. |
Specific payment method object response parameters are described with the payment method
Refund the full amount for a payment. For now, it is only possible to perform a full refund. The refund can only be performed within the payment method, which means that an iDEAL payment can only be refunded via iDEAL.
Create a refund by calling the following URL via the HTTP-POST method.
POST | /refunds/v1 |
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
amount | Decimal | 19,2 | Yes | Amount to refund. Must be equal to the amount of the payment. |
currency | String | 3 | No | Currency of amount |
reason | String | 255 | No | Reason for refund |
payment_id | String | 39 | Yes | Id of payment to refund |
Specific payment method refund parameters are described with the payment method
Name | Format | Length | Description |
---|---|---|---|
payment_id | String | 39 | Id of related payment |
refund_id | String | 39 | Id of refund |
status | String | 18 | Status of refund. Can be Succeeded, Failed or Pending |
amount | Decimal | 19,2 | Amount (to be) refunded. |
currency | String | 3 | Currency of amount |
reason | String | 255 | Reason for refund |
test | boolean | 1 | Test flag for refund (future use). True for test. |
created_at | DateTime UTC | 25 | Date of creation |
updated_at | DateTime UTC | 25 | Date of update |
Specific refund response fields parameters are described with the payment method
Creating an iDEAL charge
During the on boarding process all URL’s mentioned below have to be set. Nevertheless, these values can be overwritten. Therefore, all URL’s are optional. The on boarding defined values can be overwritten. A payment id will be appended to the specified URL if " Send payment id in url" is set to true in the merchant's dashboard.
The Payment details of the charge are :
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
issuer_id | String | 8 | Yes | ID of the bank |
success_url | String | 255 | No | Return URL when the payment is completed. |
failed_url | String | 255 | No | URL that will be used when the payment failed. |
cancelled_url | String | 255 | No | URL that will be used once the payment is cancelled |
expired_url | String | 255 | No | URL that will be used when the payment is expired. |
callback_url | String | 255 | No | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Yes | Used as a unique reference for the merchant. |
description | String | 35 | Yes | Description of the payment. |
{ "amount": 12.95, "currency": "EUR", "payments": [ { "amount": 12.95, "currency": "EUR", "payment_method": "iDEAL", "due_date": "2016-03-24T11:05:59Z", "payment_details": { "issuer_id": "INGBNL2A", "success_url": "http://www.cmpayments.com/success", "failed_url": "http://www.cmpayments.com/failed", "cancelled_url": "http://www.cmpayments.com/cancelled", "expired_url": "http://www.cmpayments.com/expired", "purchase_id": "GX32AAA", "description": "Dit is een test description" } } ] }
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest>() { new IdealPaymentRequest() { Amount = 15.0, Currency = "EUR", Details = new IdealDetailsRequest() { IssuerId = "RABONL2U", SuccessUrl = "your_redirect_url_here", FailedUrl = "your_redirect_url_here", CancelledUrl = "your_redirect_url_here", ExpiredUrl = "your_redirect_url_here", CallbackUrl = "your_callback_url_here", PurchaseId = "unique_id", Description = "your_description_here" } } } }; client.PayAsync(charge).ConfigureAwait(false);
In the response upon creation of a Charge the Charge and Payment object will maintain the same format.
Name | Format | Length | Description |
---|---|---|---|
authentication_url | String | 255 | URL to where an end-user can execute the Payment. |
callback_url | String | 255 | URL that will be used to call the merchant backend when a payment status has changed |
cancelled_url | String | 255 | Redirect location when the payment is cancelled. |
description | String | 35 | Payment description. |
expired_url | String | 255 | Redirect location when the payment is expired. |
failed_url | String | 255 | Redirect location when the payment is failed. |
Issuer_id | String | 8 | ID of the issuer. |
purchase_id | String | 35 | Unique reference for the merchant. |
success_url | String | 255 | Redirect location when the payment is successfully completed. |
transaction_id | String | 16 | Identification ID of the transaction. |
Following details are only present in case of status = "Success" | |||
paid_by_ascript | String | 70 | Name of payer |
paid_by_iban | String | 34 | IBAN of payer |
paid_by_bic | String | 11 | BIC of bank of payer |
{ "charge_id": "ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67", "status": "Open", "amount": 12.95, "currency": "EUR", "created_at": "2016-07-22T09:47:29+00:00", "updated_at": "2016-07-22T09:47:29+00:00", "payments": [ { "payment_id": "pt-804036f2-fbd8-4e3a-86c4-7212f814d464", "charge_id": "ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67", "payment_method": "iDEAL", "status": "Open", "amount": 12.95, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-22T09:47:29+00:00", "updated_at": "2016-07-22T09:47:29+00:00", "payment_details": { "authentication_url": "https://mock.cmpayments.com/ideal/v1/cmbank?transactionid=1234972658253740", "cancelled_url": "http://www.cmpayments.com/cancelled", "description": "Dit is een test description", "expired_url": "http://www.cmpayments.com/expired", "failed_url": "http://www.cmpayments.com/failed", "issuer_id": "INGBNL2A", "purchase_id": "GX32AAA", "success_url": "http://www.cmpayments.com/success", "transaction_id": "1234972658253740" } } ] }
var result = new ChargeResponse { Amount = 1.5m, ChargeId = "ch-978844a6-5812-45c5-bd04-196d721a6d33", CreatedAt = new DateTime(2017, 5, 16, 11, 23, 20), Currency = "EUR", Payments = new List<PaymentResponse> { new IdealPaymentResponse { Amount = 1.5m, ChargeId = "ch-978844a6-5812-45c5-bd04-196d721a6d33", CreatedAt = new DateTime(2017, 5, 16, 11, 23, 20), Currency = "EUR", new IdealDetailsResponse { AuthenticationUrl = "https://mock.cmpayments.com/ideal/v1/cmbank?transactionid=1234978952250909", CallbackUrl = null, CancelledUrl = "http://localhost:2654/Checkout/Method?status=cancelled", Description = "Test description.", ExpiredUrl = "", FailedUrl = "http://localhost:2654/Checkout/Failed", IssuerId = "RABONL2U", PaidByAscript = null, PaidByBic = null, PaidByIban = null, PurchaseId = "fdc1642260df409789792efcfdba8d6e", SuccessUrl = "http://localhost:2654/Checkout/Success" } DueDate = new DateTime(1, 1, 1, 0, 0, 0), ExpiresAt = new DateTime(1, 1, 1, 0, 0, 0), Method = "iDEAL", PaymentId = "pt-48d741c6-2d5f-4739-a5ea-dd8e2d02cdaa", ShortPaymentId = "2YW45P7", Status = "Open", Test = true, UpdatedAt = new DateTime(2017, 5, 16, 11, 23, 20) } }, Status = "Open", UpdatedAt = new DateTime(2017, 5, 16, 11, 23, 20) };
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 4.2
{ "charge_id": "ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67", "status": "Open", "amount": 12.95, "currency": "EUR", "created_at": "2016-07-22T09:47:29+00:00", "updated_at": "2016-07-22T09:47:29+00:00", "payments": [ { "payment_id": "pt-804036f2-fbd8-4e3a-86c4-7212f814d464", "charge_id": "ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67", "payment_method": "iDEAL", "status": "Open", "amount": 12.95, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-22T09:47:29+00:00", "updated_at": "2016-07-22T09:47:29+00:00", "payment_details": { "authentication_url": "https://mock.cmpayments.com/ideal/v1/cmbank?transactionid=1234972658253740", "cancelled_url": "http://www.cmpayments.com/cancelled", "description": "Dit is een test description", "expired_url": "http://www.cmpayments.com/expired", "failed_url": "http://www.cmpayments.com/failed", "issuer_id": "INGBNL2A", "purchase_id": "GX32AAA", "success_url": "http://www.cmpayments.com/success", "transaction_id": "1234972658253740" } } ] }
ChargeResponse response = await client.GetChargeAsync("ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67").ConfigureAwait(false);
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /payments/v1/pt-804036f2-fbd8-4e3a-86c4-7212f814d464 | ||
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 4.2.
Note: In the example the status is success and therefore the fields: paid_by script. paid_by_bic and paid_by_iban are returned with values.
{ "payment_id": "pt-804036f2-fbd8-4e3a-86c4-7212f814d464", "charge_id": "ch-3678ef39-3cb4-41b2-b6fa-d2527d61ba67", "payment_method": "iDEAL", "status": "Success", "amount": 12.95, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-22T09:47:29+00:00", "updated_at": "2016-07-22T09:50:34+00:00", "payment_details": { "authentication_url": "https://mock.cmpayments.com/ideal/v1/cmbank?transactionid=1234972658253740", "cancelled_url": "http://www.cmpayments.com/cancelled", "description": "Dit is een test description", "expired_url": "http://www.cmpayments.com/expired", "failed_url": "http://www.cmpayments.com/failed", "issuer_id": "INGBNL2A", "paid_by_ascript": "Onderheuvel", "paid_by_bic": "INGBNL2A", "paid_by_iban": "NL52INGB2088416456", "purchase_id": "GX32AAA", "success_url": "http://www.cmpayments.com/success", "transaction_id": "1234972658253740" } }
PaymentResponse response = await client.GetPaymentAsync("pt-804036f2-fbd8-4e3a-86c4-7212f814d464").ConfigureAwait(false);
As mentioned earlier, it is possible to perform a full refund. Create a refund by calling the following URL via the HTTP-POST method. The last parameter in the URL is the ID of the payment which needs to be refunded.
POST | /refunds/v1 |
{ "amount": 15.95, "currency": "EUR", "reason": "I want my money back", "payment_id": "pt-efd101c5-d641-4dc1-94e5-d16629c05b49", "refund_details": { } }
RefundRequest refund = new RefundRequest() { Amount = 15.0, Currency = "EUR", Reason = "Your_reason", PaymentId = "payment_id", Details = new IdealRefundDetails() { } }; client.RefundAsync(refund);
Besides the default parameters as described in chapter 3.1.2 Common Refund Response Fields, there are extra fields provided.
Name | Format | Length | Description |
---|---|---|---|
refund_iban | String | 34 | Bankaccount number |
refund_name | String | 255 | Name related to bank account |
refund_bic | String | 11 | BIC of bank |
purchase_id | String | 35 | Purchase id related to refund |
debit_transaction_reference | String | 36 | ID for debittransaction |
debit_transaction_status | String | 18 | Status of debittransaction |
credit_transaction_reference | String | 36 | ID for credittransaction |
credit_transaction_status | String | 18 | Status of credittransaction |
{ "payment_id": "pt-efd101c5-d641-4dc1-94e5-d16629c05b49", "refund_id": "rf-eabf9f7e-6113-4f4e-ace4-844f10d00258", "status": "Pending", "amount": 15.95, "currency": "EUR", "reason": "I want my money back", "test": true, "created_at": "2016-10-03T09:40:42+00:00", "updated_at": "2016-10-03T09:40:42+00:00", "refund_details": { "refund_iban": "NL57INGB9586456711", "refund_name": "Onderheuvel", "refund_bic": "INGBNL2A", "purchase_id": "fd6440369dc019c73c124651", "debit_transaction_reference": "56DB3D4E-7ED1-4468-8E7D-D30D83692654", "debit_transaction_status": "Pending", "credit_transaction_reference": "426CA433-DB1E-4046-952E-067998E87CE8", "credit_transaction_status": "Pending" } }
var response = new RefundResponse { PaymentId = "pt-efd101c5-d641-4dc1-94e5-d16629c05b49", RefundId = "rf-eabf9f7e-6113-4f4e-ace4-844f10d00258", Status = "Pending", Amound = 15.95, Currency = "EUR", Reason = "I want my money back", Test = true, CreatedAt = "2016-10-03T09:40:42+00:00", UpdatedAt = "2016-10-03T09:40:42+00:00", Details = new IdealRefundDetailsResponse { RefundIban = "NL57INGB9586456711", RefundName = "Onderheuvel", RefundBic = "INGBNL2A", PurchaseId = "fd6440369dc019c73c124651", DebitTransactionReference = "56DB3D4E-7ED1-4468-8E7D-D30D83692654", DebitTransactionStatus = "Pending", CreditTransactionReference = "426CA433-DB1E-4046-952E-067998E87CE8", CreditTransactionStatus = "Pending" } }
Retrieve a refund for a payment.The last parameter in the URL is the ID of the refund.
POST /refunds/v1/rf-eabf9f7e-6113-4f4e-ace4-844f10d00258 | |
{ "payment_id": "pt-efd101c5-d641-4dc1-94e5-d16629c05b49", "refund_id": "rf-eabf9f7e-6113-4f4e-ace4-844f10d00258", "status": "Pending", "amount": 15.95, "currency": "EUR", "reason": "I want my money back", "test": true, "created_at": "2016-10-03T09:40:42+00:00", "updated_at": "2016-10-03T09:40:42+00:00", "refund_details": { "refund_iban": "NL57INGB9586456711", "refund_name": "Onderheuvel", "refund_bic": "INGBNL2A", "purchase_id": "fd6440369dc019c73c124651", "debit_transaction_reference": "56DB3D4E-7ED1-4468-8E7D-D30D83692654", "debit_transaction_status": "Pending", "credit_transaction_reference": "426CA433-DB1E-4046-952E-067998E87CE8", "credit_transaction_status": "Pending" } }
RefundResponse response = await client.GetRefundAsync("rf-eabf9f7e-6113-4f4e-ace4-844f10d00258");
Retrieve a list of all the banks that act as an iDEAL issuer.
GET | /issuers/v1/ideal |
The response returned is an object containing the name and the id of the issuer, using the name of the issuer as key and the issuer id as its value.
{ "ABN Amro": "ABNANL2A", "ASN Bank": "ASNBNL21", "bunq": "BUNQNL2A", "Van Lanschot": "FVLBNL22", "ING": "INGBNL2A", "Knab": "KNABNL2H", "Rabobank": "RABONL2U", "RegioBank": "RBRBNL21", "SNS Bank": "SNSBNL2A", "Triodos Bank": "TRIONL2U" }
List<Issuer> issuers = await client.GetIssuersAsync();
Create a Single iDEAL QR Charge
A specific endpoint is to be used (see below). This specific endpoint expects a POST request of single iDEAL QR objects.
Endpoint | |
---|---|
POST | /qr/v1 |
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
amount | Decimal | 12,2 | Yes | Amount of the Payment, with a maximum precision of 2 (e.g. .34, 0.12, 12.34 or 15). The dot (.) is considered the decimal separator. |
amount_changeable | Boolean | - | Yes | Boolean if the amount can be changed in the app by the end-user. |
description | String | 95 | Yes | A short description of the payment. The description is visible within dashboard and will be shown on the end-user’s bank or card statement when possible. |
one_off | Boolean | - | Yes | Boolean if the QR code can be paid multiple times or just once. |
expiration | String | - | Yes | Expiration date of the QR code. Input can be DateTime (eg. RFC3339 format) or 'dd-mm-YYYY HH:ii'. If no TimeZone indication is present than the value must be in Europe/Amsterdam TimeZone context. |
beneficiary | String | 40 | Yes | Name of the beneficiary |
purchase_id | String | 35 | Yes | Unique alphanumeric string that serves as a reference for the merchant. |
size | Integer | 4 | Yes | Pixel width and height of the QR image. Value must be between 100 – 2000 |
amount_min | Decimal | 12,2 | No* | Minimum amount of the Payment when “amount_changeable” is true, with a maximum precision of 2 (e.g. .34, 0.12, 12.34 or 15). The dot (.) is considered the decimal separator. The end-user is not able to pay less than this amount when set. Min amount should be lower or equal to the amount. *Mandatory in case “amount_changeable” is true. |
amount_max | Decimal | 12,2 | No* | Maximum amount of the Payment when “amount_changeable” is true, with a maximum precision of 2 (e.g. .34, 0.12, 12.34 or 15). The dot (.) is considered the decimal separator. The end-user is not able to pay more than this amount when set. Max amount should be higher or equal to the amount. *Mandatory in case “amount_changeable” is true. |
success_url | String | 255 | No | Redirect location when the payment is successfully completed. |
cancelled_url | String | 255 | No | Redirect location when the payment is cancelled. |
expired_url | String | 255 | No | Redirect location when the payment is expired. |
failed_url | String | 255 | No | Redirect location when the payment is failed. |
callback_url | String | 255 | No | Location to receive status-notifications about this transaction. |
{ "amount": 24.95, "amount_changeable": true, "description": "Description of Payment", "one_off": true, "expiration": "2016-06-14 00:00", "beneficiary": "Beneficiary of Payment", "purchase_id": "PO1234567", "size": 1000, "amount_min": 19.95, "amount_max": 30.01, "success_url": "https://www.cmpayments.com/success", "failed_url": "https://www.cmpayments.com/failed", "cancelled_url": "https://www.cmpayments.com/cancelled", "expired_url": "https://www.cmpayments.com/expired", "callback_url": "https://www.cmpayments.com/callback" }
QrRequest qr = new QrRequest() { Amount = 15.0, AmountChangeable = false, AmountMax = 20.0, AmountMin = 10.0, Beneficiary = "Beneficiary of Payment", Description = "Description of Payment", Expiration = DateTime.Now, OneOff = true, PurchaseId = "PO1234567", Size = 300, SuccessUrl = "https://www.cmpayments.com/success", FailedUrl = "https://www.cmpayments.com/failed", CancelledUrl = "https://www.cmpayments.com/cancelled", CallbackUrl = "https://www.cmpayments.com/callback", ExpiredUrl = "https://www.cmpayments.com/expired" }; client.QrAsync(qr);
In the response upon creation of iDEAL QR code the Charge and Payment object will maintain the same format.
Name | Format | Length | Description |
---|---|---|---|
qr_id | String | 36 | QR code identifier. |
qr_code_url | String | 255 | URL to the QR code. |
payments | object | - | - |
status | String | null | This value is actually an enum. All possible values are explained in 5.10 iDEAL QR status codes |
amount | Decimal | 12,2 | Amount of the Payment, with a maximum precision of 2 (e.g. 0.1234). The dot (.) is considered the decimal separator. |
amount_changeable | Boolean | - | Decides if the amount can be changed in the app. Must be true or false. |
one_off | Boolean | - | Decides if the QR code can be scanned by more than one device. Must be true or false. |
expiration | Datetime | - | Expiration date of the QR code. Does not include seconds. (2016-05-14 00:00) |
beneficiary | String | 40 | Name of the beneficiary |
purchase_id | String | 35 | Unique alphanumeric string that serves as a reference for the merchant. |
size | Integer | 4 | Pixel width and height of the QR image. |
description | String | 95 | A short description of the payment. The description is visible within dashboard and will be shown on the end-user’s bank or card statement when possible. |
created_at | Datetime | - | Date of the QR code creation. Datetime in UTC |
updated_at | Datetime | null | Last update date of the QR code. Datetime in UTC, or null when QR code has never been updated before. |
{ "qr_id": "16f033f2-d032-4a23-971f-137321da24e1", "qr_code_url": "https://qrcode.ideal.nl/codes/16f033f2-d032-4a23-971f-137321da24e1", "payments": {}, "status": "Uninitialized", "amount": 24.95, "amount_changeable": true, "amount_min": 19.95, "amount_max": 30.01, "one_off": true, "expiration": "2016-06-14T00:00:00+00:00", "beneficiary": "Beneficiary of Payment", "purchase_id": "PO1234567", "size": 1000, "description": "Description of Payment", "created_at": "2016-06-03T11:00:46+00:00", "updated_at": null }
var response = QrResponse { QrId = "16f033f2-d032-4a23-971f-137321da24e1", QrCodeUrl = "https://qrcode.ideal.nl/codes/16f033f2-d032-4a23-971f-137321da24e1", Payments = {}, Status = "Uninitialized", Amount = 24.95, AmountChangeable = true, AmountMin = 19.95, AmountMax = 30.01, OneOff = true, Expiration = "2016-06-14T00:00:00+00:00", Beneficiary = "Beneficiary of Payment", PruchaseId = "PO1234567", Size = 1000, Description = "Description of Payment", CreatedAt = "2016-06-03T11:00:46+00:00", UpdatedAt = null }
Create multiple iDEAL QR charges
A specific endpoint is to be used (see below).This specific endpoint expects a POST request with an array of multiple iDEAL-QR objects.
A maximum of 750 iDEAL-QR objects per request is recommended.
Endpoint | |
---|---|
POST | /qr/v1/generate-batch |
Name | Format | Mandatory | Description |
---|---|---|---|
data | Array | Yes | This object must contain multiple charges. Properties of an individual charge are shown in the table below. JSON code example and array of multiple charges are depicted on the right. |
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
amount | Decimal | 12,2 | Yes | Amount of the Payment, with a maximum precision of 2 (e.g. .34, 0.12, 12.34 or 15). The dot (.) is considered the decimal separator. |
amount_changeable | Boolean | - | Yes | Boolean if the amount can be changed in the app by the end-user. |
description | String | 95 | Yes | A short description of the payment. The description is visible within dashboard and will be shown on the end-user’s bank or card statement when possible. |
one_off | Boolean | - | Yes | Boolean if the QR code can be paid multiple times or just once. |
expiration | String | - | Yes | Expiration date of the QR code. Input can be DateTime (eg. RFC3339 format) or 'dd-mm-YYYY HH:ii'. If no TimeZone indication is present than the value must be in Europe/Amsterdam TimeZone context. |
beneficiary | String | 40 | Yes | Name of the beneficiary |
purchase_id | String | 35 | Yes | Unique alphanumeric string that serves as a reference for the merchant. |
size | Integer | 4 | Yes | Pixel width and height of the QR image. Value must be between 100 – 2000 |
amount_min | Decimal | 12,2 | No* | Minimum amount of the Payment when “amount_changeable” is true, with a maximum precision of 2 (e.g. .34, 0.12, 12.34 or 15). The dot (.) is considered the decimal separator. The end-user is not able to pay less than this amount when set. Min amount should be lower or equal to the amount. *Mandatory in case “amount_changeable” is true. |
amount_max | Decimal | 12,2 | No* | Maximum amount of the Payment when “amount_changeable” is true, with a maximum precision of 2 (e.g. .34, 0.12, 12.34 or 15). The dot (.) is considered the decimal separator. The end-user is not able to pay more than this amount when set. Max amount should be higher or equal to the amount. *Mandatory in case “amount_changeable” is true. |
success_url | String | 255 | No | Redirect location when the payment is successfully completed. |
cancelled_url | String | 255 | No | Redirect location when the payment is cancelled. |
expired_url | String | 255 | No | Redirect location when the payment is expired. |
failed_url | String | 255 | No | Redirect location when the payment is failed. |
callback_url | String | 255 | No | Location to receive status-notifications about this transaction. |
{ "data": [ { "amount": 24.95, "amount_changeable": false, "description": "Payment A", "one_off": true, "beneficiary": "Beneficiary of Payment", "purchase_id": "PO1234567", "expiration": "2020-08-21 12:38", "size": 1000 }, { "amount": 24.95, "amount_changeable": false, "description": "Payment B", "one_off": true, "beneficiary": "Beneficiary of Payment", "purchase_id": "PO1234567", "expiration": "2020-08-21 12:38", "size": 1000 } ] }
In the response upon creation of multiple QR codes
Name | Format | Length | Description |
---|---|---|---|
qr_id | String | 36 | QR code identifier. |
qr_code_url | String | 255 | URL to the QR code. |
{ "id" : "34141e3c-815e-4f57-bdd3-26a6c3971887", "batch" : [ { "qr_id" : "dafe498f-9e0d-49ff-b3fb-82c9c0b85e78", "qr_code_url" : "https://qr3.ideal.nl/qrcode/dafe498f-9e0d-49ff-b3fb-82c9c0b85e78.png" }, { "qr_id" : "cf2ec65d-fa97-441c-bebe-4cc5bc9bb775", "qr_code_url" : "https://qr3.ideal.nl/qrcode/cf2ec65d-fa97-441c-bebe-4cc5bc9bb775.png" } ] }
Retrieve a QR code by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the qr_id
GET | /qr/v1/bac59b7f-8bf3-4b5b-af4e-7ba8191794de |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped.
The properties ‘payments’ and ‘payment_summary’ contain - when a Payment has already been started for this QR - the following;
Name | Format | Length | Description |
---|---|---|---|
payments | Object | - | The response object will contain the ids of the Charge(s) and Payment(s) associated with requested the QR code. If no Payment has been started for this QR code the response will be empty. |
payment_summary | Object | - | The response object will contain a summary of the QR code. Status of QR code, Count of status, Amount of status. |
status | String | 9 | This value is actually an enum (e.g. Success). All possible values are explained in 5.6 iDEAL QR status codes. |
count | Decimal | 12.2 | Total count of the payment_summary. |
amount | Decimal | 12.2 | Total amount of the payment_summary. The dot (.) is considered the decimal separator. |
See chapter 5.2 for a description of all properties.
Example response of a QR code for which a single Payment has been started is displayed below.
If a Payment has not yet been started for the specific QR then;
{ "qr_id" : "bac59b7f-8bf3-4b5b-af4e-7ba8191794de", "qr_code_url" : "https://qr3.ideal.nl/qrcode/bac59b7f-8bf3-4b5b-af4e-7ba8191794de.png", "payments" : { "ch-d1af878f-7ada-4e86-b816-c8cadea3ba5d" : [ "pt-ea0efd92-6c44-4ad9-af25-0302aaca22de" ] }, "status" : null, "amount" : 24.95, "amount_changeable" : false, "amount_min" : null, "amount_max" : null, "one_off" : false, "expiration" : "2021-07-20T14:36:00+00:00", "beneficiary" : "Beneficiary of Payment", "purchase_id" : "PO1234567", "size" : 1000, "description" : "Description of Payment", "created_at" : "2020-07-22T07:22:49+00:00", "updated_at" : null, "payment_summary" : [ { "status" : "success", "count" : 1, "amount" : 24.95 } ] }
QrResponse response = await client.GetQrAsync("ch-e15a1187-4e6a-43c7-9734-e19476f0e981");
This is a convenience method for getting the status of the associated Payment of a QR code.
In case a QR code can be paid multiple times (property ‘one_off’ = false), the property ‘status’ will be null.
Endpoint | ||
---|---|---|
GET | /qr/v1/status/16f033f2-d032-4a23-971f-137321da24e1 | |
A HTTP-GET request requires the body to be empty, body content that is provided will be dropped.
All possible values are explained in Chapter 5.10 iDEAL QR | status codes
{ "status": "Open" }
string status = client.GetQrStatusAsync("16f033f2-d032-4a23-971f-137321da24e1");
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge.
Endpoint | |||
---|---|---|---|
GET | /payments/v1/pt-39a06fae-deff-42b6-808d-daeebb84970a | ||
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 4.2 iDEAL Response.
Name | Format | Length | Description |
---|---|---|---|
transaction_id | String | 16 | Unique Transaction ID generated by the iDEAL backend. |
authentication_url | String | 255 | URL to where an end-user can execute the Payment, generated by the iDEAL backend. |
failed_url | String | 255 | Redirect location when the payment has failed. |
expired_url | String | 255 | Redirect location when the payment has expired. |
cancelled_url | String | 255 | Redirect location when the payment has been cancelled. |
success_url | String | 255 | Redirect location when the payment has been successfully completed. |
callback_url | String | 255 | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Unique reference for the Payment |
description | String | 95 | Payment description. |
issuer_id | String | 8 | ID of the issuer. |
{ "payment_id" : "pt-39a06fae-deff-42b6-808d-daeebb84970a", "charge_id" : "ch-ce27b9c6-5372-486b-b81d-5da3b0a16639", "payment_method" : "iDEAL", "status" : "Open", "amount" : 24.95, "currency" : "EUR", "due_date" : null, "test" : false, "created_at" : "2016-06-03T11:03:46+00:00", "updated_at" : "2016-06-03T11:03:46+00:00", "payment_details" : { "transaction_id" : "0020001281914333", "authentication_url" : "https://betalen.rabobank.nl/ideal-betaling/landingpage?random=bdaf5b9465ae0566806ec1dc7f715ed196405c6f342cdeabf28a7be0087e2866&trxid=0020001281914333", "failed_url" : "https://api.cmpayments.com/redirect/failed", "expired_url" : "https://api.cmpayments.com/redirect/expired", "cancelled_url" : "https://api.cmpayments.com/redirect/cancelled", "success_url" : "https://api.cmpayments.com/redirect/success", "purchase_id" : "PO1234567", "description" : "Description of Payment", "issuer_id" : "RABONL2U" } }
See chapter 4.5
see chapter 4.6
A QR code can have one of the following statuses:
Value | Type | Description |
---|---|---|
null | Null | Value is null when the status of a QR cannot be determined. Such is the case when dealing with a QR code with property ‘one_off’ = false. In this case there are multiple (there is no limit) Charges present for one QR. |
Uninitialized | String | No Payment has been associated with this QR code yet |
Open | String | The single Payment associated with this QR code has been started but no (payment) activity yet |
Success | String | The single Payment associated with this QR code was successfully paid in full by the end-user |
Failure | String | The single Payment associated with this QR code failed, a possible reason could be 'insufficient funds' |
Expired | String | The single Payment associated with this QR code has expired, end-user did not pay before the due_date was ended |
Cancelled | String | The single Payment associated with this QR code was cancelled, the Payment was cancelled by the end-user |
Creating an AfterPay charge
The Payment details of the charge are :
Order Object
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
portfolio_id | Integer | 1 | Yes | Id for portfolio |
password | String | 20 | Yes | Password for merchants portfolio |
bank_account_number | String | 34 | Yes | International Bank Account Number, must be compliant with ISO. ISO 13616:2007. |
ip address | String | 15 | Yes | ip address |
order_number | String | 32 | Yes | Alpha numeric string of the order number. |
invoice_number | String | 32 | Yes | Alpha numeric string of the invoice number order. |
total_order_amount | Integer | Yes | Total amount for this payment |
Order Line Object
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
article_description | String | 45 | Yes | Description of article |
vat_category | Integer | 1 | Yes | VAT category. 1:High, 2:Low, 3:Zero, 4:None, 5:Middle |
article_id | String | 25 | Yes | Article identification |
quantity | Integer | 9 | Yes | Number of articles |
unit_price | Integer | 9 | Yes | Price of article in cents |
net_unit_price | Integer | 9 | No | Net price of article in cents |
Bill to address
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
city | String | 80 | Yes | City of the billing address. |
street_name | String | 80 | Yes | Street name of the billing address. |
house_number | Integer | 12 | Yes | House number of the billing address. |
house_number_addition | String | 6 | No | House number addition of the billing address. |
Iso_country_code | String | 2 | Yes | Country of the billing address ISO 3166-1. |
postal_code | String | 12 | Yes | Zip code of the billing address. |
region | String | 80 | No | Region for billing address |
Reference Person
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
Lastname | String | 30 | Yes | Reference person’s last name |
Initials | String | 20 | Yes | Reference person’s initials. |
email_address | String | 45 | Yes | Reference person’s email address RFC 822. |
phone_number_1 | String | 10 | Yes | Primary phone number used, minimal 10 numeric characters. And maximum 10 numeric characters. |
phone_number_2 | String | 10 | Yes | Primary phone number used, minimal 10 numeric characters. And maximum 10 numeric characters. |
gender | String | 1 | Yes | Gender of the reference person, options are: m, f. |
date_of_birth | DateTime | - | Yes | Date of birth of the reference person. Date time format RFC339. |
iso_language | String | <=5 | Yes | Language of the reference person ISO 3166-1. |
Ship to address
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
city | String | 80 | Yes | City of the shipping address. |
street_name | String | 80 | Yes | Street name of the shipping address. |
house_number | Integer | 12 | Yes | House number of the shipping address. |
house_number_addition | String | 6 | No | House number addition of the shipping address. |
iso_country_code | String | 2 | Yes | Country of the shipping address ISO 3166-1. |
postal_code | String | 12 | Yes | Zip code of the shipping address. |
region | String | 80 | No | Region for shipping address |
{ "amount": 12.95, "currency": "EUR", "payments": [ { "amount": 12.95, "currency": "EUR", "payment_method": "AfterPay", "due_date": "2016-03-24T11:05:59Z", "payment_details": { "portfolio_id": "1", "password": " secretxxx", "bank_account_number": "NL55INGB0000000000", "ip_address": "127.0.0.1", "order_number": "123", "invoice_number": "123", "total_order_amount": 1295, "order_line": [ { "article_description": "Test afterpay order", "vat_category": 1, "article_id": "1234567", "unit_price": 505, "quantity": 1 }, { "article_description": "Test afterpay order 2", "vat_category": 4, "article_id": "23456", "unit_price": 790, "quantity": 1 } ], "bill_to_address": { "city": "Breda", "street_name": "Testville", "house_number": "23", "house_number_addition": "A", "iso_country_code": "NL", "postal_code": "3268 JK", "region": "Noord-Brabant", "reference_person": { "last_name": "Janssen", "initials": "KP", "email_address": "[email protected]", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568", "gender": "M", "date_of_birth": "16-11-1980", "iso_language": "NL-BE" } }, "ship_to_address": { "city": "Breda", "street_name": "Testville", "house_number": "52", "house_number_addition": "A", "iso_country_code": "NL", "postal_code": "3868 JK", "region": "Gelderland", "reference_person": { "last_name": "Janssen", "initials": "KP", "email_address": "[email protected]", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568", "gender": "M", "date_of_birth": "16-11-1980", "iso_language": "NL-BE" } } } } ] }
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest> { new AfterPayPaymentRequest { Amount = order.GetTotalCost(), Currency = "EUR", Details = new AfterPayDetailsRequest { PortfolioId = 1, Password = "de6a0cb37f", BankAccountNumber = "NL55INGB0000000000", IpAddress = this.GetIp(), OrderNumber = Guid.NewGuid().ToString("N").Substring(0, 24), InvoiceNumber = Guid.NewGuid().ToString("N").Substring(0, 15), TotalOrderAmount = (int) order.GetTotalCost(), Orderline = order.OrderItems.Select( w => new AfterPayDetailsRequest.OrderLine { ArticleDescription = w.Product.Description.Substring(0, 45), ArticleId = w.Id.ToString(), Quantity = w.Quantity, UnitPrice = (int) (w.Product.Price * 100), NetUnitPrice = (int) (w.Product.Price * 100), VatCategory = AfterPayVatCategory.High }).ToList(), BillToAddress = new AfterPayDetailsRequest.OrderAddress { City = model.City, StreetName = model.GetFormattedAddress()[0], HouseNumber = Convert.ToInt32(model.GetFormattedAddress()[1]), IsoCountryCode = "NL", PostalCode = model.PostalCode, Region = "Zuid-Holland", Reference = new AfterPayDetailsRequest.OrderAddress.ReferencePerson { LastName = model.LastName, Initials = model.GetInitials(), EmailAddress = model.Email, PhoneNumber1 = model.PhoneNumber, PhoneNumber2 = model.PhoneNumber, Gender = "M", DateOfBirth = model.DateOfBirth, IsoLanguage = "NL-BE" } }, ShipToAddress = new AfterPayDetailsRequest.OrderAddress { City = model.City, StreetName = model.GetFormattedAddress()[0], HouseNumber = Convert.ToInt32(model.GetFormattedAddress()[1]), IsoCountryCode = "NL", PostalCode = model.PostalCode, Region = "Zuid-Holland", Reference = new AfterPayDetailsRequest.OrderAddress.ReferencePerson { LastName = model.LastName, Initials = model.GetInitials(), EmailAddress = model.Email, PhoneNumber1 = model.PhoneNumber, PhoneNumber2 = model.PhoneNumber, Gender = "M", DateOfBirth = model.DateOfBirth, IsoLanguage = "NL-BE" } } } } }; }; client.PayAsync(charge).ConfigureAwait(false);
In the response upon creation of a Charge the Charge and Payment object will maintain the same format.
Order Object
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
order_number | String | 2-25 | Yes | Alpha numeric string of the order number. Must be unique per portfolio id. Must be unique for every charge. |
invoice_number | String | 2-25 | Yes | Alpha numeric string of the invoice number order. Must be unique per portfolio id. |
bank_account_number | String | 34 | Yes | Client's International Bank Account Number, must be compliant with ISO. ISO 13616:2007. |
portfolio_id | Integer | 1 | Yes | Id for portfolio (depends on order type b2c, b2b) |
password | String | 20 | Yes | Password for merchants portfolio |
ip_address | String | 45 | Yes | Valid ipv 4 or ipv 6 address. |
total_order_amount | Integer | Yes | Total amount for this payment |
Order Line Object
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
article_description | String | 45 | Yes | Description of article |
article_id | String | 25 | Yes | Article identification |
quantity | Integer | 9 | Yes | Number of articles |
unit_price | Integer | 9 | Yes | Price of article in cents |
net_unit_price | Integer | 9 | No | Net price of article in cents |
vat_category | Integer | 1 | Yes | VAT category. 1:High, 2:Low, 3:Zero, 4:None |
- | - | - | - | - |
Bill to address
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
city | String | 80 | Yes | City of the billing address. |
street_name | String | 80 | Yes | Street name of the billing address. |
house_number | Integer | 12 | Yes | House number of the billing address. |
house_number_addition | String | 6 | No | House number addition of the billing address. |
Iso_country_code | String | 2 | Yes | Country of the billing address ISO 3166-1. |
postal_code | String | 12 | Yes | Zip code of the billing address. |
region | String | 80 | No | Region for billing address |
Reference Person
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
lastname | String | 30 | Yes | Reference person’s last name |
initials | String | 20 | Yes | Reference person’s initials. |
email_address | String | 45 | Yes | Reference person’s email address RFC 822. |
phone_number_1 | String | 10 | Yes | Primary phone number used, minimal 10 numeric characters. And maximum 10 numeric characters. |
phone_number_2 | String | 10 | Yes | Secundary phone number used, minimal 10 numeric characters. And maximum 10 numeric characters. |
gender | String | 1 | Yes | Gender of the reference person, options are: m, f. |
date_of_birth | DateTime | - | Yes | Date of birth of the reference person. Date time format RFC339. |
iso_language | String | <=5 | Yes | Language of the reference person ISO 3166-1. |
Ship to address
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
city | String | 80 | Yes | City of the shipping address. |
street_name | String | 80 | Yes | Street name of the shipping address. |
house_number | Integer | 12 | Yes | House number of the shipping address. |
house_number_addition | String | 6 | No | House number addition of the shipping address. |
iso_country_code | String | 2 | Yes | Country of the shipping address ISO 3166-1. |
postal_code | String | 12 | Yes | Zip code of the shipping address. |
region | String | 80 | No | Region for shipping address |
{ "charge_id": "ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9", "status": "Open", "amount": 12.95, "currency": "EUR", "created_at": "2016-07-22T09:56:26+00:00", "updated_at": "2016-07-22T09:56:26+00:00", "payments": [ { "payment_id": "pt-17c175ff-eae8-4323-be75-e3a9b9dec165", "charge_id": "ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9", "payment_method": "AfterPay", "status": "Success", "amount": 12.95, "currency": "EUR", "due_date": "2016-03-24 11:05:59", "test": true, "created_at": "2016-07-22T09:56:26+00:00", "updated_at": "2016-07-22T09:56:26+00:00", "payment_details": { "bank_account_number": "NL55INGB0000000000", "bill_to_address": { "city": "Breda", "house_number": "23", "house_number_addition": "test", "iso_country_code": "NL", "postal_code": "3268 JK", "reference_person": { "date_of_birth": "16-11-1980", "email_address": "[email protected]", "gender": "M", "initials": "KP", "iso_language": "NL-BE", "last_name": "Janssen", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568" }, "region": "Noord-Brabant", "street_name": "Testville" }, "invoice_number": "FFIJw7BI2kDRvIwT", "ip_address": "127.0.0.1", "order_line": [ { "article_description": "Test afterpay order", "article_id": "Lvf5y1Z4M435v9P0", "quantity": "1", "unit_price": "505", "vat_category": "1" }, { "article_description": "Test afterpay order 2", "article_id": "fZsJget051YBLIQJ", "quantity": "1", "unit_price": "790", "vat_category": "4" } ], "order_number": "jpHMGP1EltKXZG3l", "password": "de6a0cb37f", "portfolio_id": "1", "result": { "checksum": "a0181e828b2ba5e90e221cd157dfb5b4", "reference": "5aca61efc02cc15b9d7f6bcb8e5f4a8", "result_id": "0", "status_code": "A", "timestamp_in": "1469181379871", "timestamp_out": "1469181385435", "transaction_id": "511814" }, "ship_to_address": { "city": "Breda", "house_number": "52", "house_number_addition": "teyt", "iso_country_code": "NL", "postal_code": "3868 JK", "reference_person": { "date_of_birth": "16-11-1980", "email_address": "[email protected]", "gender": "M", "initials": "KP", "iso_language": "NL-BE", "last_name": "Janssen", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568" }, "region": "Gelderland", "street_name": "Testville" }, "total_order_amount": "1295" } } ] }
var result = new ChargeResponse { Amount = 1.5m, ChargeId = "ch-5750159a-ff87-4c86-a32d-f5f54eccc17b", CreatedAt = new DateTime(2017, 5, 16, 13, 31, 1), Currency = "EUR", Payments = new System.Collections.Generic.List<PaymentResponse> { new AfterPayPaymentResponse { Amount = 1.5m, ChargeId = "ch-5750159a-ff87-4c86-a32d-f5f54eccc17b", CreatedAt = new DateTime(2017, 5, 16, 13, 31, 1), Currency = "EUR", new AfterPayDetailsResponse { BankAccountNumber = "NL55INGB0000000000", new AfterPayDetailsRequest.OrderAddress { City = "City", HouseNumber = 1, HouseNumberAddition = null, IsoCountryCode = "NL", PostalCode = "1234 AB", new AfterPayDetailsRequest.OrderAddress.ReferencePerson { DateOfBirth = new DateTime(1970, 01, 01, 0, 0, 0), EmailAddress = "[email protected]", Gender = "M", Initials = "J", IsoLanguage = "NL-BE", LastName = "Tester", PhoneNumber1 = "0612345678", PhoneNumber2 = "0612345678" }, Region = "Zuid-Holland", StreetName = "Street" }, IAuthenticatedResponse.AuthenticationUrl = null, InvoiceNumber = "30e981471cea4c5", IpAddress = "10.13.8.30", OrderNumber = "6fb56bbbf3e244bfbff02533", Orderline = new List<AfterPayDetailsRequest.OrderLine> { new AfterPayDetailsRequest.OrderLine { ArticleDescription = "Lorem ipsum dolor sit amet, consectetur adipi", ArticleId = "2", NetUnitPrice = 150, Quantity = 1, UnitPrice = 150, VatCategory = High } }, Password = "de6a0cb37f", PortfolioId = 1, new AfterPayDetailsResponse.ResultResponse { Checksum = "d6ae9a5a8203a24551a12b25ec5d43cf", OrderReference = "c790e54d80994823e3ab6260ecea5b6c", ResultId = 0, StatusCode = "A", TimestampIn = "1494934261573", TimestampOut = "1494934261893", TotalInvoicedAmount = 150, TotalReservedAmount = 0, TransactionId = "731217" }, new AfterPayDetailsRequest.OrderAddress { City = "City", HouseNumber = 1, HouseNumberAddition = null, IsoCountryCode = "NL", PostalCode = "1234 AB", new AfterPayDetailsRequest.OrderAddress.ReferencePerson { DateOfBirth = new DateTime(1970, 01, 01, 0, 0, 0), EmailAddress = "[email protected]", Gender = "M", Initials = "J", IsoLanguage = "NL-BE", LastName = "Tester", PhoneNumber1 = "0612345678", PhoneNumber2 = "0612345678" }, Region = "Zuid-Holland", StreetName = "Street" }, TotalOrderAmount = 1 }, DueDate = new DateTime(1, 1, 1, 0, 0, 0), ExpiresAt = new DateTime(1, 1, 1, 0, 0, 0), Method = "AfterPay", PaymentId = "pt-24cb430f-4ffe-42c9-847a-85cbd0b84ed7", ShortPaymentId = "26A35VN", Status = "Success", Test = true, UpdatedAt = new DateTime(2017, 5, 16, 13, 31, 1) } }, Status = "Success", UpdatedAt = new DateTime(2017, 5, 16, 13, 31, 1) };
Whenever an error occur, the following parameters are returned
Name | Format | Length | Description |
---|---|---|---|
code | String | 4 | Error code |
message | String | 64 | Error message |
{ "id": "d3d3a601-7ede-4cd4-9f47-71b48b185fe0.1", "error": [ { "code": 1150, "message": "Payment could not be initiated" } ] }
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 6.2
{ "charge_id": "ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9", "status": "Open", "amount": 12.95, "currency": "EUR", "created_at": "2016-07-22T09:56:26+00:00", "updated_at": "2016-07-22T09:56:26+00:00", "payments": [ { "payment_id": "pt-17c175ff-eae8-4323-be75-e3a9b9dec165", "charge_id": "ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9", "payment_method": "AfterPay", "status": "Success", "amount": 12.95, "currency": "EUR", "due_date": "2016-03-24 11:05:59", "test": true, "created_at": "2016-07-22T09:56:26+00:00", "updated_at": "2016-07-22T09:56:26+00:00", "payment_details": { "bank_account_number": "NL55INGB0000000000", "bill_to_address": { "city": "Breda", "house_number": "23", "house_number_addition": "test", "iso_country_code": "NL", "postal_code": "3268 JK", "reference_person": { "date_of_birth": "16-11-1980", "email_address": "[email protected]", "gender": "M", "initials": "KP", "iso_language": "NL-BE", "last_name": "Janssen", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568" }, "region": "Noord-Brabant", "street_name": "Testville" }, "invoice_number": "FFIJw7BI2kDRvIwT", "ip_address": "127.0.0.1", "order_line": [ { "article_description": "Test afterpay order", "article_id": "Lvf5y1Z4M435v9P0", "quantity": "1", "unit_price": "505", "vat_category": "1" }, { "article_description": "Test afterpay order 2", "article_id": "fZsJget051YBLIQJ", "quantity": "1", "unit_price": "790", "vat_category": "4" } ], "order_number": "jpHMGP1EltKXZG3l", "password": "de6a0cb37f", "portfolio_id": "1", "result": { "checksum": "a0181e828b2ba5e90e221cd157dfb5b4", "reference": "5aca61efc02cc15b9d7f6bcb8e5f4a8", "result_id": "0", "status_code": "A", "timestamp_in": "1469181379871", "timestamp_out": "1469181385435", "transaction_id": "511814" }, "ship_to_address": { "city": "Breda", "house_number": "52", "house_number_addition": "teyt", "iso_country_code": "NL", "postal_code": "3868 JK", "reference_person": { "date_of_birth": "16-11-1980", "email_address": "[email protected]", "gender": "M", "initials": "KP", "iso_language": "NL-BE", "last_name": "Janssen", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568" }, "region": "Gelderland", "street_name": "Testville" }, "total_order_amount": "1295" } } ] }
ChargeResponse response = await client.GetChargeAsync("ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9");
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /payments/v1/ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9 | ||
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 6.2.
{ "payment_id": "pt-17c175ff-eae8-4323-be75-e3a9b9dec165", "charge_id": "ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9", "payment_method": "AfterPay", "status": "Success", "amount": 12.95, "currency": "EUR", "due_date": "2016-03-24 11:05:59", "test": true, "created_at": "2016-07-22T09:56:26+00:00", "updated_at": "2016-07-22T09:56:26+00:00", "payment_details": { "bank_account_number": "NL55INGB0000000000", "bill_to_address": { "city": "Breda", "house_number": "23", "house_number_addition": "test", "iso_country_code": "NL", "postal_code": "3268 JK", "reference_person": { "date_of_birth": "16-11-1980", "email_address": "[email protected]", "gender": "M", "initials": "KP", "iso_language": "NL-BE", "last_name": "Janssen", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568" }, "region": "Noord-Brabant", "street_name": "Testville" }, "invoice_number": "FFIJw7BI2kDRvIwT", "ip_address": "127.0.0.1", "order_line": [ { "article_description": "Test afterpay order", "article_id": "Lvf5y1Z4M435v9P0", "quantity": "1", "unit_price": "505", "vat_category": "1" }, { "article_description": "Test afterpay order 2", "article_id": "fZsJget051YBLIQJ", "quantity": "1", "unit_price": "790", "vat_category": "4" } ], "order_number": "jpHMGP1EltKXZG3l", "password": "de6a0cb37f", "portfolio_id": "1", "result": { "checksum": "a0181e828b2ba5e90e221cd157dfb5b4", "reference": "5aca61efc02cc15b9d7f6bcb8e5f4a8", "result_id": "0", "status_code": "A", "timestamp_in": "1469181379871", "timestamp_out": "1469181385435", "transaction_id": "511814" }, "ship_to_address": { "city": "Breda", "house_number": "52", "house_number_addition": "teyt", "iso_country_code": "NL", "postal_code": "3868 JK", "reference_person": { "date_of_birth": "16-11-1980", "email_address": "[email protected]", "gender": "M", "initials": "KP", "iso_language": "NL-BE", "last_name": "Janssen", "phone_number_1": "076-1234-568", "phone_number_2": "076-1234-568" }, "region": "Gelderland", "street_name": "Testville" }, "total_order_amount": "1295" } }
PaymentResponse response = await client.GetPaymentAsync("ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9");
Refund the full amount for a AfterPay payment. The last parameter in the URL is the ID of the payment which needs to be refunded.
POST /refund/v1/pt-b1f64b11-a1d9-43b6-927f-7f135c5fabaf | |
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
credit_invoice_number | String | 32 | No | Number for the credit invoice |
{ "amount": 15.95, "currency": "EUR", "reason": "Refund for defect in product", "payment_id": "pt-b1f64b11-a1d9-43b6-927f-7f135c5fabaf", "refund_details": { "credit_invoice_number": "CINV43423421" } }
RefundRequest refund = new RefundRequest() { Amount = 15.0, Currency = "EUR", Reason = "Your_reason", PaymentId = "payment_id", Details = new AfterPayRefundDetails() { CreditInvoiceNumber = "CINV43423421" } }; client.RefundAsync(refund);
Besides the default parameters as described in chapter 3.1.2 Common Refund Response Fields, there are extra fields provided.
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
credit_invoice_number | String | 32 | No | Number for the credit invoice |
{ "payment_id": "pt-b1f64b11-a1d9-43b6-927f-7f135c5fabaf", "refund_id": "rf-72943c84-23f5-4e5b-a6b3-29c71fbafdb4", "status": "Succeeded", "amount": 15.95, "currency": "EUR", "reason": "Refund for defect in product", "test": true, "created_at": "2016-10-03T09:50:11+00:00", "updated_at": "2016-10-03T09:50:11+00:00", "refund_details": { "credit_invoice_number": "CINV43423421" } }
var response = new RefundResponse { PaymentId = "pt-efd101c5-d641-4dc1-94e5-d16629c05b49", RefundId = "rf-eabf9f7e-6113-4f4e-ace4-844f10d00258", Status = "Pending", Amound = 15.95, Currency = "EUR", Reason = "I want my money back", Test = true, CreatedAt = "2016-10-03T09:40:42+00:00", UpdatedAt = "2016-10-03T09:40:42+00:00", Details = new AfterPayRefundDetailsResponse { CreditInvoiceNumber = "CINV43423421" } }
Retrieve a refund for a payment.The last parameter in the URL is the ID of the refund.
POST /refunds/v1/rf-72943c84-23f5-4e5b-a6b3-29c71fbafdb4 | |
{ "payment_id": "pt-b1f64b11-a1d9-43b6-927f-7f135c5fabaf", "refund_id": "rf-72943c84-23f5-4e5b-a6b3-29c71fbafdb4", "status": "Succeeded", "amount": 15.95, "currency": "EUR", "reason": "Refund for defect in product", "test": true, "created_at": "2016-10-03T09:50:11+00:00", "updated_at": "2016-10-03T09:50:11+00:00", "refund_details": { "credit_invoice_number": "CINV43423421" } }
client.GetRefundAsync("rf-72943c84-23f5-4e5b-a6b3-29c71fbafdb4").ConfigureAwait(false);
Create a BanContact charge
The Payment details of the charge are :
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
issuers | Array | 0..3 | No | BCMC. If omitted BCMC is assumed. |
success_url | String | 255 | No | Return URL when the payment is completed. |
cancelled_url | String | 255 | No | URL that will be used once the payment is cancelled |
failed_url | String | 255 | No | URL that will be used when the payment failed. |
expired_url | String | 255 | No | URL that will be used when the payment is expired. |
callback_url | String | 255 | No | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Yes | Used as a unique reference for the merchant. |
{ "amount": 12.95, "currency": "EUR", "payments": [ { "amount": 12.95, "currency": "EUR", "payment_method": "Bancontact", "due_date": "2016-03-24T11:05:59Z", "payment_details": { "success_url": "http://www.cmpayments.com/success", "failed_url": "http://www.cmpayments.com/failed", "cancelled_url": "http://www.cmpayments.com/cancelled", "expired_url": "http://www.cmpayments.com/expired", "purchase_id": "GX32AAA" } } ] }
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest> { new BancontactPaymentRequest { Amount = "15.0", Currency = "EUR", Details = new BancontactDetailsRequest { SuccessUrl = "http://www.cmtelecom.com", FailedUrl = "http://www.cm.nl/failed", CancelledUrl = "http://www.cm.nl/cancelled", ExpiredUrl = "http://www.cm.nl/expired", PurchaseId = "GX32AAA" } } }; }; client.PayAsync(charge).ConfigureAwait(false);
In the response upon creation of a Charge the Charge and Payment object will maintain the same format.
Name | Format | Length | Description |
---|---|---|---|
success_url | String | 255 | Redirect location when the payment is successfully completed. |
cancelled_url | String | 255 | Redirect location when the payment is cancelled. |
expired_url | String | 255 | Redirect location when the payment is expired. |
failed_url | String | 255 | Redirect location when the payment is failed. |
callback_url | String | 255 | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Unique reference for the merchant |
authentication_url | String | 255 | URL to where an end-user can execute the Payment. |
Following details are only present in case of status = "Failure" or "Success" | |||
masked_pan | String | 16 | Masked bancontact cardnumber |
issuer | String | 20 | BCMC |
Following detail is only present in case of status = "Failure" | |||
reason_for_failure | String | 255 | Explanatory text for failure |
{ "charge_id": "ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8", "status": "Open", "amount": 12.95, "currency": "EUR", "created_at": "2016-07-21T12:40:35+00:00", "updated_at": "2016-07-21T12:40:35+00:00", "payments": [ { "payment_id": "pt-e69f3632-a482-4abb-ae63-91877d6c7f7f", "charge_id": "ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8", "payment_method": "Bancontact", "status": "Open", "amount": 12.95, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-21T12:40:35+00:00", "updated_at": "2016-07-21T12:40:35+00:00", "payment_details": { "authentication_url": "https://api.cmpayments.com/sipsform?pid= pt-e69f3632-a482-4abb-ae63-91877d6c7f7f", "cancelled_url": "http://www.cm.nl/cancelled", "expired_url": "http://www.cm.nl/expired", "failed_url": "http://www.cm.nl/failed", "purchase_id": "[email protected][email protected]", "success_url": "http://www.cmtelecom.com" } } ] }
var response = new ChargeResponse { Amount = 1.5m, ChargeId = "ch-726dad98-b441-40cf-9fd5-ece33dabdc7e", CreatedAt = new DateTime(2017, 5, 16, 9, 0, 23), Currency = "EUR", Payments = new List<PaymentResponse> { new BancontactPaymentResponse { Amount = 1.5m, ChargeId = "ch-726dad98-b441-40cf-9fd5-ece33dabdc7e", CreatedAt = new DateTime(2017, 5, 16, 9, 0, 23), Currency = "EUR", DueDate = new DateTime(1, 1, 1, 0, 0, 0), Method = "Bancontact", PaymentId = "pt-c863def7-c5ad-4140-ab79-19f51309f855", ShortPaymentId = "6U2KMU", Status = "Open", Test = true, UpdatedAt = new DateTime(2017, 5, 16, 9, 0, 23), Details = new BancontactDetailsResponse { AuthenticationUrl = "https://api.cmpayments.com/sipsform?pid= pt-e69f3632-a482-4abb-ae63-91877d6c7f7f", CallbackUrl = "", CancelledUrl = "http://localhost:2654/Checkout/Method?status=cancelled", ExpiredUrl = "", FailedUrl = "http://localhost:2654/Checkout/Failed", PurchaseId = "6a8a144224944f4a8e2ef09d11db9e5c", SuccessUrl = "http://localhost:2654/Checkout/Success" } } }, Status = "Open", UpdatedAt = new DateTime(2017, 5, 16, 9, 0, 23) };
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 8.2
{ "charge_id": "ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8", "status": "Open", "amount": 12.95, "currency": "EUR", "created_at": "2016-07-21T12:40:35+00:00", "updated_at": "2016-07-21T12:40:35+00:00", "payments": [ { "payment_id": "pt-e69f3632-a482-4abb-ae63-91877d6c7f7f", "charge_id": "ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8", "payment_method": "Bancontact", "status": "Open", "amount": 12.95, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-21T12:40:35+00:00", "updated_at": "2016-07-21T12:40:35+00:00", "payment_details": { "authentication_url": "https://api.cmpayments.com/sipsform?pid= pt-e69f3632-a482-4abb-ae63-91877d6c7f7f", "cancelled_url": "http://www.cm.nl/cancelled", "expired_url": "http://www.cm.nl/expired", "failed_url": "http://www.cm.nl/failed", "purchase_id": "[email protected][email protected]", "success_url": "http://www.cmtelecom.com" } } ] }
ChargeResponse response = await client.GetChargeAsync("ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8");
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /payments/v1/ch-924be0b7-0727-43ba-9f29-b70bdab3695f |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 8.2.
{ "payment_id": "pt-43cee16c-968f-419d-981f-985c898b7076", "charge_id": "ch-924be0b7-0727-43ba-9f29-b70bdab3695f", "payment_method": "Bancontact", "status": "Success", "amount": 0.02, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-19T14:54:23+00:00", "updated_at": "2016-07-19T14:54:53+00:00", "payment_details": { "authentication_url": "https://api.cmpayments.com/sipsform?pid= pt-43cee16c-968f-419d-981f-985c898b7076", "cancelled_url": "http://www.cm.nl/cancelled", "expired_url": "http://www.cm.nl/expired", "failed_url": "http://www.cm.nl/failed", "issuer": "BCMC", "masked_pan": "5017##########00", "purchase_id": "[email protected][email protected]", "success_url": "http://www.cmtelecom.com" } }
PaymentResponse response = await client.GetPaymentAsync("ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8");
Refund the full amount for a Credit Card payment. The last parameter in the URL is the ID of the payment which needs to be refunded.
POST /refund/v1/pt-2aaaf643-7a1e-4eb0-a3f4-5f35f2ce8582 | |
{ "amount": 15.95, "currency": "EUR", "reason": "Not my favorite color", "payment_id": "pt-2aaaf643-7a1e-4eb0-a3f4-5f35f2ce8582", "refund_details": { } }
The default parameters as described in chapter 3.1.2 Common Refund Response Fields.
{ "payment_id": "pt-2aaaf643-7a1e-4eb0-a3f4-5f35f2ce8582", "refund_id": "rf-801873dd-e3c8-451d-a635-44a7b698831a", "status": "Pending", "amount": 15.95, "currency": "EUR", "reason": "Not my favorite color", "test": true, "created_at": "2016-10-03T09:50:11+00:00", "updated_at": "2016-10-03T09:50:11+00:00", "refund_details": { } }
Create a SOFORT Charge
The Payment details of the charge are :
Name | Format | Length | Description |
---|---|---|---|
bank_bic | String | 11 | BIC of consumer bank |
bank_account_number | String | 34 | IBAN of consumer bank account |
consumer_name | String | 255 | Name of consumer |
success_url | String | 255 | Redirect location when the payment is successfully completed. |
cancelled_url | String | 255 | Redirect location when the payment is cancelled. |
expired_url | String | 255 | Redirect location when the payment is expired. |
callback_url | String | 255 | URL that will be used to call the merchant backend when a payment status has changed |
failed_url | String | 255 | Redirect location when the payment is failed. |
{ "amount": 27.95, "currency": "EUR", "payments": [ { "amount": 27.95, "currency": "EUR", "payment_method": "SOFORT", "payment_details": { "bank_bic": "INGBNL2A", "bank_account_number": "NL55INGB0000000000", "consumer_name": "Piet Paulusma", "success_url": "http://www.cmtelecom.com/sofort/success", "failed_url": "http://www.cmtelecom.com/sofort/failed", "cancelled_url": "http://www.cmtelecom.com/sofort/cancelled", "expired_url": "http://www.cmtelecom.com/sofort/expired", "purchase_id": "SFRTID010202", "description": "test-2016-10-03+10-49-35" } } ] }
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest> { new SofortPaymentRequest { Amount = "15.0", Currency = "EUR", Details = new SofortDetailsRequest { BankBic = "INGBNL2A", BankAccountNumber = "NL55INGB0000000000", ConsumerName = "Barteljaap Gustaaf", SuccessUrl = "http://www.cmtelecom.com", FailedUrl = "http://www.cm.nl/failed", CancelledUrl = "http://www.cm.nl/cancelled", ExpiredUrl = "http://www.cm.nl/expired", PurchaseId = "SFRTID010202", Description = "Test description" } } }; }; client.PayAsync(charge).ConfigureAwait(false);
In the response upon creation of a Charge the Charge and Payment object will maintain the same format.
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
bank_bic | String | 11 | Yes | BIC of consumer bank |
bank_account_number | String | 34 | Yes | IBAN of consumer bank account |
consumer_name | String | 255 | Yes | Name of consumer |
success_url | String | 255 | No | Return URL when the payment is completed. |
cancelled_url | String | 255 | No | URL that will be used once the payment is cancelled |
failed_url | String | 255 | No | URL that will be used when the payment failed. |
expired_url | String | 255 | No | URL that will be used when the payment is expired. |
callback_url | String | 255 | No | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Yes | Used as a unique reference for the merchant. |
description | String | 35 | Yes | Description of the payment. |
transaction_id | String | 27 | Yes | Description of the transaction. |
{ "charge_id": "ch-dce5e03f-9bb9-4851-bb3e-9f5121c1574d", "status": "Open", "amount": 27.95, "currency": "EUR", "created_at": "2016-10-03T08:50:20+00:00", "updated_at": "2016-10-03T08:50:20+00:00", "payments": [ { "payment_id": "pt-a58502ce-4196-45e2-9f5e-2ab4d0184fb2", "short_payment_id": "2Y1VEY2", "charge_id": "ch-dce5e03f-9bb9-4851-bb3e-9f5121c1574d", "payment_method": "SOFORT", "status": "Open", "amount": 27.95, "currency": "EUR", "due_date": null, "test": true, "expires_at": null, "created_at": "2016-10-03T08:50:20+00:00", "updated_at": "2016-10-03T08:50:20+00:00", "payment_details": { "authentication_url": "https://www.sofort.com/payment/go/b5670863b9c5224781a502884430cdca3b0547c1", "bank_account_number": "NL55INGB0000000000", "bank_bic": "INGBNL2A", "cancelled_url": "http://www.cmtelecom.com/sofort/cancelled", "consumer_name": "Piet Paulusma", "description": "test-2016-10-03+10-49-35", "expired_url": "http://www.cmtelecom.com/sofort/expired", "failed_url": "http://www.cmtelecom.com/sofort/failed", "purchase_id": "SFRTID010202", "success_url": "http://www.cmtelecom.com/sofort/success", "transaction_id": "114765-236573-57F21BCC-77D4" } } ] }
var result = new ChargeResponse { Amount = 1.5m, ChargeId = "ch-afcf8e73-af98-4e4e-85e4-9b00d3c0fcb2", CreatedAt = new DateTime(2017, 5, 16, 11, 18, 8), Currency = "EUR", Payments = new List<Model.PaymentResponse> { new SofortPaymentResponse { Amount = 1.5m, ChargeId = "ch-afcf8e73-af98-4e4e-85e4-9b00d3c0fcb2", CreatedAt = new DateTime(2017, 5, 16, 11, 18, 8), Currency = "EUR", DueDate = new DateTime(1, 1, 1, 0, 0, 0), ExpiresAt = new DateTime(1, 1, 1, 0, 0, 0), Method = "SOFORT", PaymentId = "pt-17d5326a-7191-4f4c-9e74-bc2301f98833", ShortPaymentId = "3E9PBLZ", Status = "Open", Test = true, UpdatedAt = new DateTime(2017, 5, 16, 11, 18, 8), Details = new SofortDetailsResponse { AuthenticationUrl = "https://www.sofort.com/payment/go/1d72a90fa4311e2f727f6c80697b6c5ab1a5e", BankAccountNumber = "NL55INGB0000000000", BankBic = "RABONL2U", CallbackUrl = null, CancelledUrl = "http://localhost:2654/Checkout/Method?status=cancelled", ConsumerName = "Barteljaap Gustaaf", Description = "Test description", ExpiredUrl = "", FailedUrl = "http://localhost:2654/Checkout/Failed", PurchaseId = "6a8a144224944f4a8e2ef09d11db9e5c", SuccessUrl = "http://localhost:2654/Checkout/Success", TransactionId = "114765-236573-591AC3D0-C54B" } } }, Status = "Open", UpdatedAt = new DateTime(2017, 5, 16, 11, 18, 8) };
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-dce5e03f-9bb9-4851-bb3e-9f5121c1574d |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 9.2
{ "charge_id": "ch-dce5e03f-9bb9-4851-bb3e-9f5121c1574d", "status": "Open", "amount": 27.95, "currency": "EUR", "created_at": "2016-10-03T08:50:20+00:00", "updated_at": "2016-10-03T08:50:20+00:00", "payments": [ { "payment_id": "pt-a58502ce-4196-45e2-9f5e-2ab4d0184fb2", "short_payment_id": "2Y1VEY2", "charge_id": "ch-dce5e03f-9bb9-4851-bb3e-9f5121c1574d", "payment_method": "SOFORT", "status": "Open", "amount": 27.95, "currency": "EUR", "due_date": null, "test": true, "expires_at": null, "created_at": "2016-10-03T08:50:20+00:00", "updated_at": "2016-10-03T08:50:20+00:00", "payment_details": { "authentication_url": "https://www.sofort.com/payment/go/b5670863b9c5224781a502884430cdca3b0547c1", "bank_account_number": "NL55INGB0000000000", "bank_bic": "INGBNL2A", "cancelled_url": "http://www.cmtelecom.com/sofort/cancelled", "consumer_name": "Piet Paulusma", "description": "test-2016-10-03+10-49-35", "expired_url": "http://www.cmtelecom.com/sofort/expired", "failed_url": "http://www.cmtelecom.com/sofort/failed", "purchase_id": "SFRTID010202", "success_url": "http://www.cmtelecom.com/sofort/success", "transaction_id": "114765-236573-57F21BCC-77D4" } } ] }
ChargeResponse response = await client.GetChargeAsync("ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8");
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /payments/v1/ch-317ba229-5666-4008-914b-c251e98c1579 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 9.2
{ "payment_id": "pt-1a5b6935-f018-4496-92d3-db4436ce00f6", "short_payment_id": "3V63ZLU", "charge_id": "ch-317ba229-5666-4008-914b-c251e98c1579", "payment_method": "SOFORT", "status": "Accepted", "amount": 27.95, "currency": "EUR", "due_date": null, "test": true, "expires_at": null, "created_at": "2016-10-03T09:11:12+00:00", "updated_at": "2016-10-03T09:16:59+00:00", "payment_details": { "authentication_url": "https://www.sofort.com/payment/go/6c43ae4abd1e5084d348ff00366c8089262e45dc", "bank_account_number": "NL55INGB0000000000", "bank_bic": "INGBNL2A", "cancelled_url": "http://www.cmtelecom.com/sofort/cancelled", "consumer_name": "Jan Jansen", "description": "test-2016-10-03+11-10-59", "expired_url": "http://www.cmtelecom.com/sofort/expired", "failed_url": "http://www.cmtelecom.com/sofort/failed", "purchase_id": "SFRTID010202", "success_url": "http://www.cmtelecom.com/sofort/success", "transaction_id": "114765-236573-57F21BCC-77D4" } }
PaymentResponse response = await client.GetPaymentAsync("ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8");
Refund the full amount for a SOFORT Refund. The last parameter in the URL is the ID of the payment which needs to be refunded.
POST /refund/v1/pt-6b868554-5171-4b99-9bce-398e33728e23 | |
{ "amount": 15.95, "currency": "EUR", "reason": "Wrong size. Please refund money.", "payment_id": "pt-6b868554-5171-4b99-9bce-398e33728e23", "refund_details": { } }
Name | Format | Length | Description |
---|---|---|---|
refund_name | String | 255 | Name related to bank account |
refund_iban | String | 34 | Bankaccount number |
refund_bic | String | 11 | BIC of bank |
purchase_id | String | 35 | Purchase id related to refund |
debit_transaction_reference | String | 36 | ID for debittransaction |
debit_transaction_status | String | 18 | Status of debittransaction |
debit_transaction_reference | String | 36 | ID for credittransaction |
credit_transaction_status | String | 18 | Status of credittransaction |
{ "payment_id": "pt-6b868554-5171-4b99-9bce-398e33728e23", "refund_id": "rf-33eaeb31-dd27-4a88-a6eb-fdf4b8f69971", "status": "Pending", "amount": 15.95, "currency": "EUR", "reason": " Wrong size. Please refund money.", "test": true, "created_at": "2016-11-21T09:58:57+00:00", "updated_at": "2016-11-21T09:58:57+00:00", "refund_details": { "refund_iban": "NL56SFRT0012345678", "refund_name": "Jan Jansen", "refund_bic": "SFRTNL20XXX", "purchase_id": "db72fc44e2ee92d085f449dd", "debit_transaction_reference": "032E7DD6-F8B8-417C-90B7-FAF0445EAF59", "debit_transaction_status": "Pending", "credit_transaction_reference": "6B502413-3114-48BC-831A-F4D5BABECEFF", "credit_transaction_status": "Pending" } }
Create a PayPal Charge
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
success_url | String | 255 | No | Return URL when the payment is completed. |
cancelled_url | String | 255 | No | URL that will be used once the payment is cancelled |
failed_url | String | 255 | No | URL that will be used when the payment failed. |
expired_url | String | 255 | No | URL that will be used when the payment is expired. |
callback_url | String | 255 | No | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Yes | Used as a unique reference for the merchant. |
description | String | 35 | Yes | Description of the payment. |
{ "amount": 12.95, "currency": "EUR", "payments": [ { "amount": 12.95, "currency": "EUR", "payment_method": "PayPal", "payment_details": { "success_url": "http://www.cmpayments.com/success", "failed_url": "http://www.cmpayments.com/failed", "cancelled_url": "http://www.cmpayments.com/cancelled", "expired_url": "http://www.cmpayments.com/expired", "purchase_id": "cba865031d3a878d905f0a74", "description": "This is the description of your payment. It is shown to the user during payment." } } ] }
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest> { new PayPalPaymentRequest { Amount = order.GetTotalCost(), Currency = "EUR", Details = new PayPalDetailsRequest { SuccessUrl = "http://www.cmtelecom.com", FailedUrl = "http://www.cm.nl/failed", CancelledUrl = "http://www.cm.nl/cancelled", ExpiredUrl = "http://www.cm.nl/expired", PurchaseId = "cba865031d3a878d905f0a74", Description = "Test description." } } }; }; client.PayAsync(charge).ConfigureAwait(false);
In the response upon creation of a Charge the Charge and Payment object will maintain the same format.
Name | Format | Length | Description |
---|---|---|---|
success_url | String | 255 | Redirect location when the payment is successfully completed. |
cancelled_url | String | 255 | Redirect location when the payment is cancelled. |
expired_url | String | 255 | Redirect location when the payment is expired. |
failed_url | String | 255 | Redirect location when the payment is failed. |
callback_url | String | 255 | URL that will be used to call the merchant backend when a payment status has changed |
purchase_id | String | 35 | Unique reference for the merchant |
authentication_url | String | 255 | URL to where an end-user can execute the Payment. |
Following details are only present in case of status = "Success" or “Refunded” | |||
fee_amount | String | 4 | Transaction costs PayPal charged for transaction |
fee_currency | String | 3 | Currency in which PayPal charged transaction costs |
payer_city | String | 255 | City of the user who paid the charge |
payer_email | String | 255 | E-mail address of the user who paid the charge |
payer_first_name | String | 255 | First name of the user who paid the charge |
payer_last_name | String | 255 | Last name of the user who paid the charge |
{ "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "created_at" : "2016-09-19T14:16:20+00:00", "updated_at" : "2016-09-19T14:16:20+00:00", "payments" : [ { "payment_id" : "pt-b561a53a-e6f3-4948-9315-242536d60b79", "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "payment_method" : "PayPal", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "due_date" : null, "test" : true, "created_at" : "2016-09-19T14:16:20+00:00", "updated_at" : "2016-09-19T14:16:20+00:00", "payment_details" : { "authentication_url" : "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-30773585MD8169421", "cancelled_url" : "http://www.cmtelecom.com/ideal/cancelled", "description" : "This is the description of your payment. It is shown to the user during payment.", "expired_url" : "http://www.cmtelecom.com/ideal/expired", "failed_url" : "http://www.cmtelecom.com/ideal/failed", "purchase_id" : "cba865031d3a878d905f0a74", "success_url" : "http://www.cmtelecom.com/ideal/success", "transaction_id" : "PAY-8M018899PP604872CK7P7GMY" } } ] }
var result = new ChargeResponse { Amount = 1.5m, ChargeId = "ch-750f4adc-cf35-428e-9418-dc2f97211955", CreatedAt = new DateTime(2017, 5, 16, 11, 24, 50), Currency = "EUR", Payments = new List<PaymentResponse> { new PayPalPaymentResponse { Amount = 1.5m, ChargeId = "ch-750f4adc-cf35-428e-9418-dc2f97211955", CreatedAt = new DateTime(2017, 5, 16, 11, 24, 50), Currency = "EUR", new PayPalDetailsResponse { Amount = null, AuthenticationUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-1RA23689CU020225H", CallbackUrl = null, CancelledUrl = "http://localhost:2654/Checkout/Method?status=cancelled", City = null, Currency = null, Description = "Test description.", Email = null, ExpiredUrl = "", FailedUrl = "http://localhost:2654/Checkout/Failed", Firstname = null, Lastname = null, PurchaseId = "f989c1557dad49cc87e09c5b89efe6f3", SuccessUrl = "http://localhost:2654/Checkout/Success" }, DueDate = new DateTime(1, 1, 1, 0, 0, 0), ExpiresAt = new DateTime(1, 1, 1, 0, 0, 0), Method = "PayPal", PaymentId = "pt-a2f789be-bbd3-40d8-a771-fb19dca066e4", ShortPaymentId = "44WFAYH", Status = "Open", Test = true, UpdatedAt = new DateTime(2017, 5, 16, 11, 24, 50) } }, Status = "Open", UpdatedAt = new DateTime(2017, 5, 16, 11, 24, 50) };
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-edf0ea35-f89d-426e-bb2a-5d486250c8e9 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 10.2
{ "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "created_at" : "2016-09-19T14:16:20+00:00", "updated_at" : "2016-09-19T14:16:20+00:00", "payments" : [ { "payment_id" : "pt-b561a53a-e6f3-4948-9315-242536d60b79", "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "payment_method" : "PayPal", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "due_date" : null, "test" : true, "created_at" : "2016-09-19T14:16:20+00:00", "updated_at" : "2016-09-19T14:16:20+00:00", "payment_details" : { "authentication_url" : "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-30773585MD8169421", "cancelled_url" : "http://www.cmtelecom.com/ideal/cancelled", "description" : "This is the description of your payment. It is shown to the user during payment.", "expired_url" : "http://www.cmtelecom.com/ideal/expired", "failed_url" : "http://www.cmtelecom.com/ideal/failed", "purchase_id" : "cba865031d3a878d905f0a74", "success_url" : "http://www.cmtelecom.com/ideal/success", "transaction_id" : "PAY-8M018899PP604872CK7P7GMY" } } ] }
ChargeResponse response = await client.GetChargeAsync("ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8");
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /payments/v1/ch-806782c7-4b5b-4438-8924-c3e381314c62 | ||
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 10.2.
PaymentResponse response = await client.GetPaymentAsync("ch-0d4a8414-80f9-4f94-b639-ccd9f3b2bac8");
Refund the full amount for a PayPal Refund. The last parameter in the URL is the ID of the payment which needs to be refunded.
POST /refund/v1/pt-27d3739f-8bfb-479d-8de8-9f23494a4bca | |
{ "amount": 15.95, "currency": "EUR", "reason": "Not as expected.", "payment_id": "pt-27d3739f-8bfb-479d-8de8-9f23494a4bca", "refund_details": { } }
Name | Format | Length | Description |
---|---|---|---|
paypal.id | String | 17 | ID of refund transaction |
paypal.create_time | DateTime UTC | 34 | Date of creation for transaction |
paypal.update_time | DateTime UTC | 11 | Date of update for transaction |
paypal.state | String | 8 | Transaction state : See chapter 4.1.2 for the states |
paypal.amount.total | Decimal | 10 | Amount for refund |
paypal.amount.currency | String | 3 | Currency of amount |
paypal.sale_id | String | 36 | ID of the Sale transaction |
paypal.parent_payment | String | 18 | ID of the PayPal payment |
paypal.links.0.href | String | 255 | Url to related PayPal object |
paypal.links.0.rel | String | 14 | Sort of relation : self = refund |
paypal.links.0.method | String | 7 | Http method to be used with Url |
paypal.links.1.href | String | 255 | Url to related PayPal object |
paypal.links.1.rel | String | 14 | Sort of relation : parent_payment = related payment object |
paypal.links.1. method | String | 7 | Http method to be used with Url |
paypal.links.2.href | String | 255 | Url to related PayPal object |
paypal.links.2.rel | String | 14 | Sort of relation : sale = related sale |
paypal.links.2. method | String | 7 | Http method to be used with Url |
{ "payment_id": "pt-27d3739f-8bfb-479d-8de8-9f23494a4bca", "refund_id": "rf-16732e81-cc87-4e25-bd0f-097e1aaa04a7", "status": "Succeeded", "amount": 15.95, "currency": "EUR", "reason": "Not as expected.", "test": true, "created_at": "2016-11-21T10:45:16+00:00", "updated_at": "2016-11-21T10:45:16+00:00", "refund_details": { "paypal.id": "6CD14390YA748862S", "paypal.create_time": "2016-11-21T10:45:16Z", "paypal.update_time": "2016-11-21T10:45:16Z", "paypal.state": "completed", "paypal.amount.total": "15.95", "paypal.amount.currency": "EUR", "paypal.sale_id": "96541744818498925", "paypal.parent_payment": "PAY-5MR32854ED7081525LAZMWUY", "paypal.links.0.href": "https://api.sandbox.paypal.com/v1/payments/refund/6CD14390YA748862S", "paypal.links.0.rel": "self", "paypal.links.0.method": "GET", "paypal.links.1.href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-5MR32854ED7081525LAZMWUY", "paypal.links.1.rel": "parent_payment", "paypal.links.1.method": "GET", "paypal.links.2.href": "https://api.sandbox.paypal.com/v1/payments/sale/96541744818498925", "paypal.links.2.rel": "sale", "paypal.links.2.method": "GET" } }
Create a Wire Transfer charge
Name | Format | Length | Description |
---|---|---|---|
Purchase_id | String | 35 | Unique reference for the merchant |
{ "amount": 12.95, "currency": "EUR", "payments": [ { "amount": 12.95, "currency": "EUR", "payment_method": "WireTransfer", "expires_at": "2016-10-06T13:44:31Z", "payment_details": { "purchase_id": "cba865031d3a878d905f0a74", } } ] }
Not supported yet in .NET.
In the response upon creation of a Charge the Charge and Payment object will maintain the same format.
Name | Format | Length | Description | |
---|---|---|---|---|
beneficiary_bic | String | 11 | Unique identification code for a financial institution. This is the | BIC-code of the IBAN that CM-Payments is using. This bank-code has to be used for transfers outside the Netherlands. |
beneficiary_iban | String | 34 | The IBAN of CM-Payments to send money to. | |
beneficiary_name | String | 255 | The name of the holder of the IBAN | |
payment_description | String | 39 | A unique (short) code that the end-user has to use as description by the transaction. The length could vary over time. | |
Purchase_id | String | 35 | Unique reference for the merchant |
{ "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "created_at" : "2016-09-19T14:16:20+00:00", "updated_at" : "2016-09-19T14:16:20+00:00", "payments" : [ { "payment_id" : "pt-b561a53a-e6f3-4948-9315-242536d60b79", "short_payment_id" : "NZS3UW", "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "payment_method" : "WireTransfer", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "due_date" : null, "test" : true, "expires_at" : "2016-10-06T13:44:31+00:00", "created_at" : "2016-10-05T13:49:54+00:00", "updated_at" : "2016-10-05T13:49:54+00:00", "payment_details" : { "beneficiary_bic" : "RABONL2U", "beneficiary_iban" : "NL79RABO0302692231”, "beneficiary_name" : "Stichting Derdengelden CM Payments", "payment_description " : "NZS3UW", "purchase_id" : "cba865031d3a878d905f0a74", } } ] }
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-e15a1187-4e6a-43c7-9734-e19476f0e981 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 11.2
{ "payment_id" : " pt-d18f59ec-00ef-4f6e-911c-5327bf70d99b", "short_payment_id" : "NZS3UW", "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "payment_method" : "WireTransfer", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "due_date" : null, "test" : true, "expires_at" : "2016-10-06T13:44:31+00:00", "created_at" : "2016-10-05T13:49:54+00:00", "updated_at" : "2016-10-05T13:49:54+00:00", "payment_details" : { "beneficiary_bic" : " RABONL2U ", "beneficiary_iban" : "NL79RABO0302692231", "beneficiary_name" : "Stichting Derdengelden CM Payments", "payment_description" : "NZS3UW", "purchase_id" : "cba865031d3a878d905f0a74", }
Not supported yet in .NET.
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /payments/v1/ch-e15a1187-4e6a-43c7-9734-e19476f0e981 | |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 11.2.
{ "payment_id" : " pt-d18f59ec-00ef-4f6e-911c-5327bf70d99b", "short_payment_id" : "NZS3UW", "charge_id" : "ch-e15a1187-4e6a-43c7-9734-e19476f0e981", "payment_method" : "WireTransfer", "status" : "Open", "amount" : 15.95, "currency" : "EUR", "due_date" : null, "test" : true, "expires_at" : "2016-10-06T13:44:31+00:00", "created_at" : "2016-10-05T13:49:54+00:00", "updated_at" : "2016-10-05T13:49:54+00:00", "payment_details" : { "beneficiary_bic" : " RABONL2U ", "beneficiary_iban" : "NL79RABO0302692231", "beneficiary_name" : "Stichting Derdengelden CM Payments", "payment_description" : "NZS3UW", "purchase_id" : "cba865031d3a878d905f0a74", }
Not supported yet in .NET.
Using a SEPA DirectDebit ("automatische incasso"), funds can be withdrawn from the consumer their bank account directly. The consumer will have the option to reverse the transaction ("storneren").
In addition to the common charge fields, the following fields are supported for DirectDebit payments:
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
bank_account_number | String | 15~31 | Yes | The IBAN of the end user |
name | String | 8 | Yes | The name for the bank account |
mandate_id | String | 35 | Yes | Unique identification of the mandate |
mandate_start_date | Date | 10 | Yes | Date at which the mandate was obtained |
transaction_description | String | 100 | No | Optional description that will be shown on the end user their bank statement. If transaction_description is not provided, description will be used. |
{ "amount": 12.34, "currency": "EUR", "payments": [ { "amount": 12.34, "currency": "EUR", "payment_method": "DirectDebit", "expires_at": "2017-05-16T07:58:15Z", "payment_details": { "purchase_id": "66ee4566c67dc8bbcc0705a5", "bank_account_number": "NL52CMPT0000000020", "name": "Johnny Test", "description": "Test @ 20170515 095815", "mandate_id": "f972a87b41b0c294821fdca3", "mandate_start_date": "2017-05-15", "transaction_description": "Your purchase from OurShop" } } ] }
In addition to the common response fields, the following information is available:
Name | Format | Length | Description |
---|---|---|---|
bank_account_number | String | 15~31 | The IBAN of the end user |
name | String | 255 | The name for the bank account |
mandate_id | String | 35 | Unique identification of the mandate. |
mandate_start_date | Date | 10 | Date at which the mandate was obtained. |
transaction_description | String | 100 | Description that will be shown on the end user their bank statement. |
finalized_on | Date | 10 | Date at which the payment succeeded |
reverse_reason_code | String | 4 | Code indicating why a payment was reversed. Only present of payment_status is 'Reversed' |
reverse_reason_description | String | 100 | Description matching reverse_reason_code |
{ "charge_id" : "ch-1484e7fe-c601-4433-99c1-1c1fa249ac32", "status" : "Open", "amount" : 12.34, "currency" : "EUR", "created_at" : "2017-05-15T08:01:11+00:00", "updated_at" : "2017-05-15T08:01:11+00:00", "payments" : [ { "payment_id" : "pt-3ab3a8ef-7ec7-4e28-98ff-69fb42cc2c29", "short_payment_id" : "HBCWE3", "charge_id" : "ch-1484e7fe-c601-4433-99c1-1c1fa249ac32", "payment_method" : "DirectDebit", "status" : "Open", "amount" : 12.34, "currency" : "EUR", "due_date" : null, "test" : true, "expires_at" : "2017-05-16T08:01:08+00:00", "created_at" : "2017-05-15T08:01:11+00:00", "updated_at" : "2017-05-15T08:01:11+00:00", "payment_details" : { "bank_account_number" : "NL52CMPT0000000020", "cancelled_url": "http://www.cmpayments.com/cancelled", "description" : "Test @ 20170515 100108", "expired_url" : "http://www.cmpayments.com/expired", "failed_url" : "http://www.cmpayments.com/failed", "mandate_id" : "c8fca4f25571bf31fc035c4d", "mandate_start_date" : "2017-05-15", "name" : "Johnny Test", "purchase_id" : "1c281ff8284257174715c596", "success_url": "http://www.cmpayments.com/success", "transaction_description": "Your purchase from OurShop" "transaction_id" : "caea570d-4b79-48a6-9e3b-e65d73838239" } } ] }
Retrieve a single charge by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested charge
GET | /charges/v1/ch-1484e7fe-c601-4433-99c1-1c1fa249ac32 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as in chapter 12.2
Retrieve a single payment by calling the following URL via the HTTP-get method. The last parameter in the URL is the ID of the requested payment
GET | /payments/v1/pt-3ab3a8ef-7ec7-4e28-98ff-69fb42cc2c29 |
A HTTP-get request requires the body to be empty, any body content that is provided will be dropped. The response parameters will be the same as the payments node in chapter 12.2
As mentioned earlier, it is only possible to perform a full refund. Create a refund by calling the following URL via the HTTP-POST method. The last parameter in the URL is the ID of the payment which needs to be refunded.
POST | /refunds/v1/pt-3ab3a8ef-7ec7-4e28-98ff-69fb42cc2c29 |
{ "amount": 12.34, "currency": "EUR", "reason": "I want my money back", "payment_id": "pt-3ab3a8ef-7ec7-4e28-98ff-69fb42cc2c29", "refund_details": { "description": "test-2017-05-15+10-05-18" } }
Besides the default parameters as described in chapter 3.1.2 Common Refund Response Fields, there are extra fields provided.
Name | Format | Length | Description |
---|---|---|---|
refund_iban | String | 34 | Bankaccount number |
refund_name | String | 255 | Name related to bank account |
refund_bic | String | 11 | BIC of bank |
purchase_id | String | 35 | Purchase id related to refund |
debit_transaction_reference | String | 36 | ID for debittransaction |
debit_transaction_status | String | 18 | Status of debittransaction |
credit_transaction_reference | String | 36 | ID for credittransaction |
credit_transaction_status | String | 18 | Status of credittransaction |
{ "payment_id" : "pt-3ab3a8ef-7ec7-4e28-98ff-69fb42cc2c29", "refund_id" : "rf-aa59466d-0f71-4b37-8ed9-69d4b99f6530", "status" : "Pending", "amount" : 12.34, "currency" : "EUR", "reason" : "A reason", "test" : true, "created_at" : "2017-05-15T08:05:26+00:00", "updated_at" : "2017-05-15T08:05:26+00:00", "refund_details" : { "refund_iban" : "NL52CMPT0000000020", "refund_name" : "Johnny Test", "purchase_id" : "1c281ff8284257174715c596", "debit_transaction_reference" : "2f280d2f-7e7f-43d7-a98b-a4bf193de7ed", "debit_transaction_status" : "Pending", "credit_transaction_reference" : "3bf74d69-c57a-4f02-ab20-653a22d11050", "credit_transaction_status" : "Pending" } }
Retrieve a refund for a payment.The last parameter in the URL is the ID of the refund.
GET /refunds/v1/rf-eabf9f7e-6113-4f4e-ace4-844f10d00258 | |
{ "payment_id" : "pt-3ab3a8ef-7ec7-4e28-98ff-69fb42cc2c29", "refund_id" : "rf-aa59466d-0f71-4b37-8ed9-69d4b99f6530", "status" : "Pending", "amount" : 12.34, "currency" : "EUR", "reason" : "A reason", "test" : true, "created_at" : "2017-05-15T08:05:26+00:00", "updated_at" : "2017-05-15T08:05:26+00:00", "refund_details" : { "refund_iban" : "NL52CMPT0000000020", "refund_name" : "Johnny Test", "purchase_id" : "1c281ff8284257174715c596", "debit_transaction_reference" : "2f280d2f-7e7f-43d7-a98b-a4bf193de7ed", "debit_transaction_status" : "Pending", "credit_transaction_reference" : "3bf74d69-c57a-4f02-ab20-653a22d11050", "credit_transaction_status" : "Pending" } }
To test all different possible scenario's that can occur when using the DirectDebit payment method, a list of fictional IBANs can be used. Each IBAN will result in a different status.
Note: These IBANs only work when using a test account on the CM Payments API.
To make sure you are updated when the status of a payment is modified CM Payments provides a callback functionality. With this callback CM Payments will HTTP(S) POST the Payment id(s) of a payment to the backend URL provided by the merchant in the merchant portal.
For security purposes we only notify you with the Payment id which has an updated status. With this Payment Id you can manually retrieve - as described in chapter 5.1 - the Payment (and its updated status). This way you are able to update your own administration.
The posted data will look exactly like this: an array containing keys that represent an entity, each key value will also be an array containing entity ids of entity type defined by the key.
{
"charges": [
"ch-90b7fb11-f73a-4de2-b3ab-adfc016a1b00"
],
"payments": [
"pt-2f74da90-0d34-45ca-8886-8de8f89a5be7"
]
}
When we send a callback we check your http status code. We consider a status code of 200 a valid status code. If we cannot reach the backand URL you supplied the Request will be queued to be retried at a later time.
It’s very important to as the merchant to make sure that if everything is working as it should be to return a 200 http status code. This way we will not have to retry the callback.
Every request send to our API needs to be signed. For authentication we are using OAuth 1.0a protocol.
Note: all variables mentioned in this chapter are fictional and for demo purposes only.
If the .NET SDK is used, requests are authenticated automatically.
When using PHP and Guzzle, a middleware that handles authentication is available.