CM payments offers a solution for online payment transactions. The system supports several payment methods eg iDEAL, 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 which 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 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.
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 |
| | | | |
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 |
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest>() }
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 , Success 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. |
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, Success 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. |
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 | /refund/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" } } ] }
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/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.
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 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-efd101c5-d641-4dc1-94e5-d16629c05b49 |
{ "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() { } };
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" } }
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 iDEAL QR Charge
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 and is not mandatory and may only be used once. |
amount_changeable | Boolean | - | Yes | Boolean if the amount can be changed in the app by the end-user. |
description | String | 95 | Yes | Contains more information about the QR code. |
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 something like '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 and is not mandatory and may only be used once.The end-user is not able to pay less than this amount when set. |
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 and is not mandatory and may only be used once. The end-user is not able to pay more than this amount when set. |
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" };
In the response upon creation of a Charge 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 6.5 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 and is not mandatory and may only be used once. |
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 | Contains more information about the QR code. |
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 }
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/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.
See chapter 6.2 Response properties for the properties, but with one extra explanation: The property ‘payments’ contains - 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 an empty object. |
An optional different value for the property ‘payments’ is possible when retrieving a QR code. Other than that the response is equal to the response described in 3.1.4 Response example.
An 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": "16f033f2-d032-4a23-971f-137321da24e1", "qr_code_url": "https://qrcode.ideal.nl/codes/16f033f2-d032-4a23-971f-137321da24e1", "payments": { "ch-ce27b9c6-5372-486b-b81d-5da3b0a16639": [ "pt-3a38e7ad-f5cd-4fe3-add2-df3ec65efd41" ], "status": "Open", "amount": 24.95, "amount_changeable": true, "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-02T12:52:39+00:00", "updated_at": null }
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 when dealing with a QR code with property ‘one_off’ = true. When dealing with a QR code with property ‘one_off’ = false, the property ‘status’ will always be null. (The same status can also be retrieved when retrieving the Payment (object) associated with the requested QR. Please have a look at chapter Payment).
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.
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 |
{ "status": "Open" }
string status = client.GetQrStatusAsync("16f033f2-d032-4a23-971f-137321da24e1");
Name | Format | Length | Description |
---|---|---|---|
charge_id | String | 39 | Unique ID of the Charge. |
qr_id | String | 39 | Unique ID of the associated QR code. |
status | String | 9 | For an overview of all available statuses please have a look at 5.1.4 Status codes. |
amount | Decimal | 19,4 | The amount of the Charge. |
currency | String | 3 | Currency used for the Charge in ISO-4217 format. |
created_at | DateTime | - | Creation date of the Charge. Datetime in UTC |
updated_at | DateTime | - | Datetime when the Charge was last updated. Datetime in UTC |
payments | Array | - | Associated Payment of the Charge. Have a look at 5.1.2 Response properties for information about the Payment properties. |
Name | Format | Length | Description |
---|---|---|---|
payment_id | String | 39 | The amount that will be paid by an end-user. |
charge_id | String | 39 | Charge id linked to the payment object. |
payment_method | String | 30 | Payment method used to make the payment. |
Available payment method is: 'iDEAL'. |status|String|9|For an overview of all available statuses please have a look at 6.9.5 Status codes. |amount|Decimal|19,4|Amount of the Payment. |currency|String|3|Currency of the Payment in ISO-4217 format. |due_date|DateTime|-|Expiration date of the Payment. |test|Boolean|-|Indication of Payment was created in test modus. Test mode is dependent on Merchant’ 'test' property. |created_at|DateTime|-|Creation date of the Payment. Datetime in UTC |updated_at|DateTime|-|Datetime when the Payment was last updated. Datetime in UTC
{ "charge_id" : "ch-ce27b9c6-5372-486b-b81d-5da3b0a16639", "qr_id" : "16f033f2-d032-4a23-971f-137321da24e1", "status" : "Open", "amount" : 24.95, "currency" : "EUR", "created_at" : "2016-06-03T11:03:46+00:00", "updated_at" : "2016-06-03T11:03:46+00:00", "payments" : [ { "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" } } ] }
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-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 10.2.
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.7
see chapter 4.8
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" } } ] }
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" } };
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" } }
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" } }
Creating a Credit Card charge
The Payment details of the charge are :
Name | Format | Length | Mandatory | Description |
---|---|---|---|---|
issuers | Array | 0..3 | No | MasterCard, VISA. If omitted all issuers will be available on the paypage. |
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. |
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest> { new CreditcardPaymentRequest { Amount = "15.0", Currency = "EUR", Capture = true, Details = new CreditcardDetailsRequest { Issuers = new[] {"MasterCard", "VISA"}, SuccessUrl = "http://www.cmtelecom.com", FailedUrl = "http://www.cm.nl/failed", CancelledUrl = "http://www.cm.nl/cancelled", ExpiredUrl = "http://www.cm.nl/expired", PurchaseId = "[email protected][email protected]" } } }; };
ChargeRequest charge = new ChargeRequest { Amount = 15.0, Currency = "EUR" Payments = new List<PaymentRequest> { new CreditcardPaymentRequest { Amount = order.GetTotalCost(), Currency = "EUR", Capture = true, Details = new CreditcardDetailsRequest { Issuers = new[] {"MasterCard", "VISA"}, SuccessUrl = "http://www.cmtelecom.com", FailedUrl = "", CancelledUrl = "", ExpiredUrl = "", PurchaseId = Guid.NewGuid().ToString("N") } } }; }; client.PayAsync(charge).ConfigureAwait(false);
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 creditcardnumber |
issuer | String | 20 | MasterCard or VISA |
Following detail is only present in case of status = "Failure" | |||
reason_for_failure | String | 255 | Explanatory text for failure |
{ "charge_id": "ch-806782c7-4b5b-4438-8924-c3e381314c62", "status": "Open", "amount": 0.01, "currency": "EUR", "created_at": "2016-07-22T10:07:11+00:00", "updated_at": "2016-07-22T10:07:11+00:00", "payments": [ { "payment_id": "pt-e8b21955-26cb-4388-9885-08e4e7cc5d89", "charge_id": "ch-806782c7-4b5b-4438-8924-c3e381314c62", "payment_method": "Creditcard", "status": "Open", "amount": 0.01, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-22T10:07:11+00:00", "updated_at": "2016-07-22T10:07:11+00:00", "payment_details": { "authentication_url": "https://api. cmpayments.com/sipsform?pid=pt-e8b21955-26cb-4388-9885-08e4e7cc5d89", "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" } } ] }
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-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 7.2
{ "charge_id": "ch-806782c7-4b5b-4438-8924-c3e381314c62", "status": "Open", "amount": 0.01, "currency": "EUR", "created_at": "2016-07-22T10:07:11+00:00", "updated_at": "2016-07-22T10:07:11+00:00", "payments": [ { "payment_id": "pt-e8b21955-26cb-4388-9885-08e4e7cc5d89", "charge_id": "ch-806782c7-4b5b-4438-8924-c3e381314c62", "payment_method": "Creditcard", "status": "Open", "amount": 0.01, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-22T10:07:11+00:00", "updated_at": "2016-07-22T10:07:11+00:00", "payment_details": { "authentication_url": "https://api. cmpayments.com/sipsform?pid=pt-e8b21955-26cb-4388-9885-08e4e7cc5d89", "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-806782c7-4b5b-4438-8924-c3e381314c62");
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 7.2.
{ "payment_id": "pt-e8b21955-26cb-4388-9885-08e4e7cc5d89", "charge_id": "ch-806782c7-4b5b-4438-8924-c3e381314c62", "payment_method": "Creditcard", "status": "Success", "amount": 0.01, "currency": "EUR", "due_date": "2016-07-22 11:05:59", "test": true, "created_at": "2016-07-22T10:07:11+00:00", "updated_at": "2016-07-22T10:08:17+00:00", "payment_details": { "authentication_url": "https://api.cmpayments.com/sipsform?pid=pt-e8b21955-26cb-4388-9885-08e4e7cc5d89", "cancelled_url": "http://www.cm.nl/cancelled", "expired_url": "http://www.cm.nl/expired", "failed_url": "http://www.cm.nl/failed", "issuer": "MasterCard", "masked_pan": "5017##########00", "purchase_id": "[email protected][email protected]", "success_url": "http://www.cmtelecom.com" } }
PaymentResponse response = await client.GetPaymentAsync("ch-806782c7-4b5b-4438-8924-c3e381314c62");
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-d64f2438-433a-4336-b74f-4692750b8101 | |
{ "amount": 15.95, "currency": "EUR", "reason": "Not entirely satisfied with the quality of product", "payment_id": "pt-d64f2438-433a-4336-b74f-4692750b8101", "refund_details": { } }
The default parameters as described in chapter 3.1.2 Common Refund Response Fields.
{ "payment_id": "pt-d64f2438-433a-4336-b74f-4692750b8101", "refund_id": " rf-2de110a5-d8a7-4fe6-a7bc-8d45481c4970", "status": "Pending", "amount": 15.95, "currency": "EUR", "reason": "Not entirely satisfied with the quality of product", "test": true, "created_at": "2016-10-03T09:50:11+00:00", "updated_at": "2016-10-03T09:50:11+00:00", "refund_details": { } }
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" } } ] }
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" } } ] }
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" } } ] }
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.
Not implemented yet
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.
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'.
Collecting the request method and URL To produce a signature, start by determining the HTTP method and URL of the request. These two are known when creating the request, so they are easy to obtain, so for example;
For this specific URL and Method there is no query string mandatory, for example purposes however we will this one time include a query string parameter!
HTTP Method | POST |
---|---|
Base URL | https://< |
Collecting parameters
Next, gather all of the parameters included in the request. There are two such locations for these additional parameters, the URL (as part of the query string) and the request body. In the HTTP request the parameters are URL encoded, but you should collect the raw values. In addition to the request parameters, every oauth_* parameter needs to be included in the signature, so collect those too. For all mandatory parameters please have a look at 7.2 Collecting parameters section. An overview of all the required parameters is shown below;
{"amount":15.95,"currency":"EUR","payments":[{"amount":15.95,"currency":"EUR","payment_method":"iDEAL","payment_details":{"issuer_id":"INGBNL2A","success_url":"https:\/\/www.cmpayments.com\/charge\/success","failed_url":"https:\/\/www.cmpayments.com\/ideal\/failed","cancelled_url":"https:\/\/www.cmpayments.com\/ideal\/cancelled","expired_url":"https:\/\/www.cmpayments.com\/ideal\/expired","purchase_id":"GX32AAA","description":"test description"}}]} | |
exampleParameter | value |
exampleParameter | value |
oauth_consumer_key | xvz1evFS4wEEPTGEFPHBog |
oauth_nonce | 32f3c8c2b06e96ec8e19eb4d39672720 |
oauth_signature_method | HMAC-SHA256 |
oauth_timestamp | 1443539180 |
oauth_version | 1.0 |
These values need to be encoded into a single string which will be used later on. The process to build the string is very specific:
a. Append the encoded key (if there is one) to the output string.
b. Append the '=' character (only if there is a key) to the output string.
c. Append the encoded value to the output string.
d. If there are more key/value pairs remaining, append a '&' character to the output string.
The following string will be produced by repeating these steps with the parameters collected above:
Parameter string | {"amount":15.95,"currency":"EUR","payments":[{"amount":15.95,"currency":"EUR","payment_method":"iDEAL","payment_details":{"issuer_id":"INGBNL2A","success_url":"https:\/\/www.cmpayments.com\/charge\/success","failed_url":"https:\/\/www.cmpayments.com\/ideal\/failed","cancelled_url":"https:\/\/www.cmpayments.com\/ideal\/cancelled","expired_url":"https:\/\/www.cmpayments.com\/ideal\/expired","purchase_id":"GX32AAA","description":"test description"}}]}&exampleParameter=value&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog&oauth_nonce=32f3c8c2b06e96ec8e19eb4d39672720&oauth_signature_method=HMAC-SHA256&oa uth_timestamp=1443539180&oauth_version=1.0 |
Creating the signature base string
The three values collected so far must be joined to make a single string, from which the signature will be generated. This is called the signature base string by the OAuth specification.
To encode the HTTP method, base URL, and parameter string into a single string:
This will produce the following:
Signature base string | POST&https%3A%2F%2Fapi.cmpayments.com%2Fcharges%2Fv1%3FexampleParameter%3Dvalue&%7B%22amount%22%3A15.95%2C%22currency%22%3A%22EUR%22%2C%22payments%22%3A%5B%7B%22amount%22%3A15.95%2C%22currency%22%3A%22EUR%22%2C%22payment_method%22%3A%22iDEAL%22%2C%22payment_details%22%3A%7B%22issuer_id%22%3A%22INGBNL2A%22%2C%22success_url%22%3A%22https%3A%5C%2F%5C%2Fwww.cmpayments.com%5C%2Fcharge%5C%2Fsuccess%22%2C%22failed_url%22%3A%22https%3A%5C%2F%5C%2Fwww.cmpayments.com%5C%2Fideal%5C%2Ffailed%22%2C%22cancelled_url%22%3A%22https%3A%5C%2F%5C%2Fwww.cmpayments.com%5C%2Fideal%5C%2Fcancelled%22%2C%22expired_url%22%3A%22https%3A%5C%2F%5C%2Fwww.cmpayments.com%5C%2Fideal%5C%2Fexpired%22%2C%22purchase_id%22%3A%22GX32AAA%22%2C%22description%22%3A%22test%20description%22%7D%7D%5D%7D%26exampleParameter%3Dvalue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3D32f3c8c2b06e96ec8e19eb4d39672720%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1443539180%26oauth_version%3D1.0 |
Make sure to URL encode the parameter string! The signature base string should contain exactly 2 ampersand '&' characters. The per cent ‘%’ characters in the parameter string should be encoded as %25 in the signature base string.
Getting a signing key
The last pieces of data to collect are secrets which identify the application making the request, and the user the request is on behalf of. It is very important to note that these values are incredibly sensitive and should never be shared with anyone.
OAuth Consumer Key | xvz1evFS4wEEPTGEFPHBog |
OAuth Consumer Secret | LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE |
Once again, it is very important to keep these values private to your application only. If you feel that your values have been compromised, please contact us immediately.
Both of these values need to be combined to form a signing key which will be used to generate the signature. The signing key is simply the URL encoded OAuth Consumer Key, followed by an ampersand character '&', followed by the URL encoded OAuth Consumer Secret:
Signing key | xvz1evFS4wEEPTGEFPHBog&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE |
Calculating the signature
Finally, the signature is calculated by passing the signature base string and signing key to the HMAC-SHA256 hashing algorithm. Thankfully there are implementations of HMAC-SHA256 available for every popular language. For example, PHP has the hash_hmac function.
The output of the HMAC signing function is a binary string. This needs to be base64 encoded to produce the signature string. For example, the output given the base string and signing key given on this page is.
7e 8c 02 bf c0 92 e1 74 ef 26 26 f3 d4 4e 34 4c 0f bd 68 32 b7 5d c0 46 05 19 00 24 60 e4 ce ef
This value, when converted to base64, is the OAuth signature for this request:
oauth_signature | N2U4YzAyYmZjMDkyZTE3NGVmMjYyNmYzZDQ0ZTM0NGMwZmJkNjgzMmI3NWRjMDQ2MDUxOTAwMjQ2MGU0Y2VlZg== |