Introduction
The Paymentwindow is the easiest way to get a payment through for your order.
It simply requires a form that is submitted towards onpay.io containing the details of the payment to be made, after the customer has paid they are returned to an url selected by you.
Post form
<form method="post" action="https://onpay.io/window/v3/" accept-charset="UTF-8">
<input type="hidden" name="onpay_gatewayid" value="20007895654">
<input type="hidden" name="onpay_currency" value="DKK">
<input type="hidden" name="onpay_amount" value="12000">
<input type="hidden" name="onpay_reference" value="AF-847824">
<input type="hidden" name="onpay_hmac_sha1" value="f31dc4b392c6a7a25815e3e2bc39bc0fe02cc5a7">
<input type="hidden" name="onpay_accepturl" value="https://example.com/accept">
<input type="submit" value="Start payment of 120.00 DKK">
</form>
The form should be rendered, and submitted in the cardholders browser, and submitted against https://onpay.io/window/v3/
Parameters
Below is a list of all parameters the window supports, any parameter not prefixed with onpay_
will be passed on to the different callbacks/redirects.
Parameter | Value | Description | Example |
---|---|---|---|
onpay_gatewayid* | [0-9]+ |
The unique gatewayid for your paymentgateway | 20007895654 |
onpay_currency* | [0-9]{3} or [A-Z]{3} |
The ISO4217 currency code, either 3 digit numeric or alpha code 1 | DKK or 208 |
onpay_amount* | [0-9]+ |
The amount for the order, in minor units. If type is subscription this value is ignored. |
12000 For 120.00 DKK. |
onpay_reference* | [a-zA-Z0-9\-\.]{1,36} |
Has to be unique, your own internal reference, even tho both upper and lower case is accepted they are treated the same in the system | AF-847824 |
onpay_hmac_sha1* | [a-f0-9]+ |
A SHA1 HMAC of all parameteres ordered alphabetically and the shared secret set in the management panel. See here for more details on calculating the hash. | a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 |
onpay_accepturl* | Valid URL | Where to send the user after a successful reservation is made. | https://example.com/accept |
onpay_website* | Valid URL | URL to the website where the checkout process was started | https://example.com/ |
onpay_type | transaction or subscription |
Defaults to transaction |
transaction |
onpay_method | card , mobilepay , mobilepay_checkout , viabill , anyday or applepay |
If none is provided, the user is presented with a choice of which method to use. | |
onpay_delivery_disabled | no-reason , not-physical , store-pick-up , parcel-shop-selected , parcel-shop-auto |
Used only with method mobilepay_checkout . If set, there will be no prompt for delivery address during checkout flow, and reason is sent on to MobilePay. |
|
onpay_3dsecure | forced |
If set to forced , then all creditcard transactions are required to run with 2-factor authentication if provided by the card brand. |
|
onpay_language | da , de , en , es , fo , fr , it , nl , no , pl or sv |
The language of the payment window. Defaults to English | en |
onpay_declineurl | Valid URL | Where to send the user in case payment failed, if this value is not set the accepturl will be used! | https://example.com/decline |
onpay_callbackurl | Valid URL | If set, onpay system will make a direct call to this URL to signal that a payment suceeded. See more here | https://example.com/callback |
onpay_design | [a-zA-Z0-9 ]+ |
The name of the window design to use. Use if you have more than one design defined in the backend | window1 |
onpay_expiration | [0-9]+ |
Seconds that the payment will be available before expiring. Default is 1 day (86400 seconds). | 4200 |
onpay_testmode | [01] |
If set to 1 the window will run in testmode, provided that it has been enabled. It is only necessary to set this parameter if production mode is also enabled | 1 |
onpay_subscription_with_transaction | [01] |
Set along with onpay_type=subscription and a valid value in onpay_amount . When set to 1, a transaction will be created from the subscription on completion, with the amount defined in onpay_amount |
1 |
onpay_info_* | Additional info about the customer, see Info parameters |
Methods
The following methods are supported. When a specific method is sent to the payment window, the cardholder will be redirected to said method. If none is provided, the user is presented with a choice of which method to use.
Method | Parameter | Description |
---|---|---|
Credit card | card |
Payment using credit cards |
MobilePay Online | mobilepay |
Payment using MobilePay Online |
MobilePay Online Checkout | mobilepay_checkout |
Payment through MobilePay Online Checkout |
ViaBill | viabill |
Payment using ViaBill |
Anyday Split | anyday |
Payment using Anyday Split |
Info parameters
Besides the payment specific parameters, it is mandated by the card-schemes that further details should be provided if they are available. This is used to conduct 3DSv2, the updated standard for cardholder authentication according to the rule set forth in PSD2.
The data is utilized by the card issuer to make a risk assessment on the transaction, and determine whether to do what is called a "frictionless flow". A frictionless flow, means that the cardholder will not be prompted to enter any data but the transaction will still be marked as validated with 3D-Secure.
Parameter | Value | Description | Example |
---|---|---|---|
onpay_info_account_id | \w{1,64} |
Account identifier, could be a customer number. | ABC-455454 |
onpay_info_account_date_created | date | When the account was created at the merchant. | 2020-02-15 |
onpay_info_account_date_change | date | When the account was last changed, this includes billing and shipping address. | 2020-03-02 |
onpay_info_account_date_password_change | date | When the account last had its password changed. | 2020-03-02 |
onpay_info_account_purchases | [0-9]+ |
The number of completed purchases with this account in the last 6 months (excluding the current one). | 3 |
onpay_info_account_attempts | [0-9]+ |
The number of payment attempts on this account in the past 24 hours. | 0 |
onpay_info_account_shipping_first_use_date | date | The date of when the shipping address was first used on this account. | 2020-02-15 |
onpay_info_account_shipping_identical_name | Y , N |
Indicates whether the account holder name matches the shipping details. | Y |
onpay_info_account_suspicious | Y , N |
Indicates whether the merchant has experienced suspicious actitivy on the account previously (including fraud) | N |
onpay_info_account_attempts_day | [0-9]+ |
Number of transactions attempted (successful or not) for this account, in the past 24 hours. | 3 |
onpay_info_account_attempts_year | [0-9]+ |
Number of transactions attempted (successful or not) for this account, in the past 365 days. | 3 |
onpay_info_address_identical_shipping | Y , N |
Indicates whether the billing and shipping address are the same, only relevant if actually shipping anything. | Y |
onpay_info_billing_address_city | .{1,50} |
Billing address city | Skanderborg |
onpay_info_billing_address_country | [0-9]{3} |
Billing address country code, in the numeric format from ISO-3166-1 | 208 |
onpay_info_billing_address_line1 | .{1,50} |
First line of the address | Højvangen 4 |
onpay_info_billing_address_line2 | .{1,50} |
Second line of the address, if needed. | |
onpay_info_billing_address_line3 | .{1,50} |
Third line of the address, if needed. | |
onpay_info_billing_address_postal_code | \w{1,16} |
The postal code of the address. | 8660 |
onpay_info_billing_address_state | \w{1,3} |
The subdivision code of the address, according to ISO-3166-2 (Only the part after the country code, so US-NY becomes NY . Should only be used when relevant for the country. |
NY |
onpay_info_shipping_address_city | .{1,50} |
Shipping address city | Skanderborg |
onpay_info_shipping_address_country | [0-9]{3} |
Shipping address country code, in the numeric format from ISO-3166-1 | 208 |
onpay_info_shipping_address_line1 | .{1,50} |
First line of the address | Højvangen 4 |
onpay_info_shipping_address_line2 | .{1,50} |
Second line of the address, if needed. | |
onpay_info_shipping_address_line3 | .{1,50} |
Third line of the address, if needed. | |
onpay_info_shipping_address_postal_code | .{1,16} |
The postal code of the address. | 8660 |
onpay_info_shipping_address_state | .{1,3} |
The subdivision code of the address, according to ISO-3166-2 (Only the part after the country code, so US-NY becomes NY . Should only be used when relevant for the country. |
NY |
onpay_info_name | .{2,45} |
The name of the cardholder/customer | Emil Pedersen |
onpay_info_email | .{1,254} |
The email address of the customer | emil@example.org |
onpay_info_phone_home_cc | [0-9]{1,3} |
The country code part of the phone number | 45 |
onpay_info_phone_home_number | [0-9]{1,15} |
The actual phone number, without the country part. | 37123456 |
onpay_info_phone_mobile_cc | [0-9]{1,3} |
The country code part of the phone number | 45 |
onpay_info_phone_mobile_number | [0-9]{1,15} |
The actual phone number, without the country part. | 37123456 |
onpay_info_phone_work_cc | [0-9]{1,3} |
The country code part of the phone number | 45 |
onpay_info_phone_work_number | [0-9]{1,15} |
The actual phone number, without the country part. | 37123456 |
onpay_info_delivery_email | .{1,254} |
Only used for electronic delivery. | emil@example.org |
onpay_info_delivery_time_frame | 01 , 02 , 03 , 04 |
Indicates the delivery timeframe. 01 = Electronic, 02 = Same-day shipping, 03 = Overnight shipping, 04 = Two-day or more shipping | 03 |
onpay_info_gift_card_amount | [0-9]+ |
The total amount of all gift cards within the order, only major units. (DKK 123.45 is 123) | 123 |
onpay_info_gift_card_count | [0-9]+ |
The total quantity of gift cards within the order. | 1 |
onpay_info_preorder | Y , N |
Indicates if this order is a pre-order. A pre-order is an order for an item that has not yet been released to the market. | N |
onpay_info_preorder_date | date | For a pre-ordered purchase, the expected date that merchandise will be available | 2020-04-01 |
onpay_info_reorder | Y , N |
Indicates if this order is a re-order of a previous one | N |
onpay_info_shipping_method | 01 , 02 , 03 , 04 , 05 , 06 , 07 |
The shipping method for the transaction, use the one that best describes the order. Physical goods takes precedence over digital, and then the most expensive if multiple shipping methods for same order. 01 = Ship to billing address, 02 = Ship to another verified address, 03 = Ship to other, 04 = "Ship to store" store address should be set in shipping address fields, 05 = Digital goods, 06 = Travel & event tickets, 07 = Other (digital services, electronic subscriptions, etc.) | 01 |
Callbacks/Redirects
All called url's will contain these parameters as URL query parameters, any system set to receive these URL's should gracefully handle additional parameters prefixed with onpay_
.
Name | Type | Description | Present |
---|---|---|---|
onpay_uuid | string | Unique identifier for the transaction/subscription | Always |
onpay_number | number | The transaction or subscription number | Always |
onpay_reference | string | The provided internal reference | Always |
onpay_amount | number | The amount for the transaction, in minor units | Transactions only |
onpay_currency | string | The ISO4217 numeric currency code | Always |
onpay_hmac_sha1 | string | A SHA1 HMAC, see here for more details on calculating the hash. | Always |
onpay_method | string | The payment method used to complete the payment | Always |
onpay_3dsecure | number | Will be set to 1, if the payment was done with 3DSecure | Conditional |
onpay_testmode | number | Will be set to 1, if the payment was done in test mode | Conditional |
onpay_cardmask | string | Will contain the cardmask if a card payment was done, example 445566XXXXXX1234 | Conditional |
onpay_cardtype | string | Will contain the type of card used, if a card payment was done | Conditional |
onpay_cardcountry | number | Will contain the country code of the card ISO-3166-1, if a card payment was done. | Conditional |
onpay_acquirercode | string | On declines this parameter will contain the acquirer specific error code. | Conditional |
onpay_errorcode | string | On gateway failure this parameter will contain an error code. | Conditional |
onpay_uuid_transaction | string | Unique identifier for transaction created from subscription | Conditional |
onpay_number_transaction | number | Number for transaction created from subscription | Conditional |
Accept url
Upon successful completion of the payment authorization, the cardholder will be redirected to this URL.
We recommend always checking the onpay_hmac_sha1
value, to avoid any tampering.
Decline url
If the cardholder fails to complete the payment authorization, they will be redirected to this URL.
Callback url
The system will do an out of band asynchronous call to this url, containing the same parameters as the accept url.
Be aware that callbacks are executed from a simple HTTP client, which is unable to render javascript or load any images.
Only HTTP and HTTPS url's are accepted (on standard ports 80 & 443), if using HTTPS which is highly recommended a valid certificate chain has to be present.
SHA1 HMAC calculation
<?php
$secret = 'e88ebc73104651e3c8ee9af666c19b0626c9ecacd7f8f857e3633e355776baad92e67b7faf9b87744f8c6ce4303978ed65b4165f29534118c882c0fd95f52d0c';
function calculateSecret(array $params, $secret) {
// Step 1, grab the onpay_* params and order them alphabetically
$toHashArray = [];
foreach ($params as $key => $value) {
if (0 === strpos($key, 'onpay_') && 'onpay_hmac_sha1' !== $key) {
$toHashArray[$key] = $value;
}
}
ksort($toHashArray);
// Step 2, convert to a query string, and lower case
$queryString = strtolower(http_build_query($toHashArray));
// Output: onpay_accepturl=https%3a%2f%2fexample.com%2faccept&onpay_amount=12000&onpay_currency=dkk&onpay_gatewayid=20007895654&onpay_reference=af-847824
// Step 3 calculate the SHA1 HMAC
$hmac = hash_hmac('sha1', $queryString, $secret);
return $hmac;
}
$formParams = [
'onpay_gatewayid' => '20007895654',
'onpay_currency' => 'DKK',
'onpay_amount' => '12000',
'onpay_reference' => 'AF-847824',
'onpay_accepturl' => 'https://example.com/accept',
'unrelated_param' => 'bla bla bla',
];
echo calculateSecret($formParams, $secret);
// Output: 16586ad0b3446b58df92446296cf821500ac57d8
var secret = "e88ebc73104651e3c8ee9af666c19b0626c9ecacd7f8f857e3633e355776baad92e67b7faf9b87744f8c6ce4303978ed65b4165f29534118c882c0fd95f52d0c";
var formParams = new Dictionary<string, string>
{
{"onpay_gatewayid", "20007895654"},
{"onpay_currency", "DKK"},
{"onpay_amount", "12000"},
{"onpay_reference", "AF-847824"},
{"onpay_accepturl", "https://example.com/accept"},
{"unrelated_param", "bla bla bla"}
};
// Step 1, grab the onpay_* params and order them alphabetically
var onpayParams = formParams
.Where(x => x.Key.StartsWith("onpay_"))
.Where(x => x.Key != "onpay_hmac_sha1")
.OrderBy(x => x.Key)
.ToArray();
// Step 2, convert to a query string, and lowercase the result
var queryString = string.Join("&", onpayParams.Select(x => HttpUtility.UrlEncode(x.Key) + "=" + HttpUtility.UrlEncode(x.Value))).ToLower();
// Output: onpay_accepturl=https%3a%2f%2fexample.com%2faccept&onpay_amount=12000&onpay_currency=dkk&onpay_gatewayid=20007895654&onpay_reference=af-847824
// Step 3 calculate the SHA1 HMAC
var hashString = "";
using (var sha1 = new HMACSHA1(Encoding.UTF8.GetBytes(secret)))
{
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(queryString));
hashString = string.Join("", hash.Select(x => x.ToString("x2")));
// Output: 16586ad0b3446b58df92446296cf821500ac57d8
}
The SHA1 is calculated as an HMAC hash, over all onpay_* parameters.
- Order the onpay_* parameters alphabetically (excluding the onpay_hmac_sha1)
- Convert the list of parameters to a query string, and lower case the result
- Calculate SHA1 HMAC against the query string 2