NAV Navbar
PHP C#
  • Introduction
  • Post form
  • Callbacks/Redirects
  • SHA1 HMAC calculation
  • 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_type payment or subscription Defaults to payment payment
    onpay_method card, mobilepay, mobilepay_checkout, or viabill If none is provided, the user is presented with a choice of which method to use. card
    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_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_info_* Additional info about the customer, see Info parameters

    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_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

    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.

    1. Order the onpay_* parameters alphabetically (excluding the onpay_hmac_sha1)
    2. Convert the list of parameters to a query string, and lower case the result
    3. Calculate SHA1 HMAC against the query string 2