PayU | Express

1 Introduction

PayU|Express is based on a transparent integration type which allows the Merchant to accept card payments without redirecting users to a page hosted by the payment service provider. This integration type retains the security level and minimizes the PCI DSS compliance effort. It is also meant to give the Merchant more flexibility and increase conversion rates through better control over the payment process.

A payment flow is based on two steps - invoking the widget or using the form to capture card credentials in a secure way (front-end process) and then using them to create a payment transaction (back-end process). Card credentials are returned in the form of a token and a masked card number, therefore the Merchant never receives full card details. Back-end processing is based on the OpenPayU protocol and integration is made easier through available SDKs.

Tokens received from PayU can be either single-use or multi-use. Multi-use tokens can be stored and used for future payments. Typically such functionality can be used by e.g. a merchant who has an extensive database of returning users – linking a user account with a multi-use token improves user experience, because the user no longer needs to enter card data each time. Usually, transactions initiated with a stored token can be made with only a single click of the “Pay” button, however for security reasons, such transactions may sometimes require 3D Secure authentication or CVV2/CVC2 prompt depending on a PayU risk assessment. Therefore, it is assumed that the cardholder is present when the transaction is made.

PayU configuration

The PayU | Express service requires configuration operations to be performed at PayU side. Therefore, before starting the integration process, please contact PayU via your Account Manager.

Security requirements and recommendations

Before integrating the service, please take a look at the requirements and recommendations prepared by our security experts. It will help you protect yourself against frauds.

2 Integration overview

PayU | Express is based on tokenization. Steps:
  • (first payment) tokenize the card, you may use form or PayU widget, PayU sends back single-use token
  • (first payment) send Order with single-use token, PayU sends back multi-use token
  • (second and next payments) send Order with multi-use token

Transparent payment with a single-use token (first payment):

Transparent payment with a multi-use token (second and next payments):

3 Widget

There are two options for capturing the card data: via a widget hosted by PayU or by including PayU scripts to scan input fields in your website. The widget has two versions: pop-up (displayed over your website) and inline (embedded into your website).
Note: in case of an inline widget or your own inputs, you should display text provided in the Information Requirements section.

3.1 Pop-up widget

This section provides information on the pop-up widget. It may either use POST method or a callback function to provide output.

Output example:

   value:"TOK_1IOPVS7EMKVT4GYvs44XPxAOb8yc",
   maskedCard:"424242******4242",
   tokenType:"STANDARD",
   type:"CARD_TOKEN"
Parameter name Description
value one-time token ("TOK_") - expires after first usage
maskedCard masked card number
tokenType fixed value (always STANDARD)
type fixed value (always CARD_TOKEN)

Widget implementation has 3 steps:

1. Include the payment form presenting a payment button that defines a payment handling action. To do this, define a correct action parameter.
                    <form action="http://exampledomain.payu.com/processOrder.php" method="post">
                        <button id="pay-button">Pay now</button>
                    </form>
                

2. Include the PayU widget bootstrap JS script. Define all the parameters according to your needs and POS configuration.

Note: the widget can pass the data via POST method or through a callback function provided in success-callback parameter. Compare the inline widget example below.

                    <script
                        src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                        pay-button="#pay-button"
                        merchant-pos-id="145227"
                        shop-name="Shop name"
                        total-amount="9.99"
                        currency-code="PLN"
                        customer-language="en"
                        store-card="true"
                        customer-email="email@exampledomain.com"
                        sig="6c9bb18db84165f53b5918380833723bc5fbb95ec5a9b73a4cb02dd60c11c64e">
                    </script>
                

3. Calculate the SIG parameter necessary to secure communication. Widget parameters and SIG algorithm: Widget parameters.

In some cases, even for multi-use token transations, PayU may ask for CVV. Then CVV Widget should be displayed:
                    <script
                        src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                        merchant-pos-id="145227"
                        shop-name="Shop name"
                        total-amount="9.99"
                        currency-code="PLN"
                        customer-language="pl"
                        widget-type="cvv"
                        cvv-url="refReqId=c4b31c492b0a5aaa9eb12d07578286a0"
                        cvv-success-callback="cvvSuccess"
                        sig="e08f617240bac43954bcbb5782a0ce203a23717ba9760be71c9ea8cab127ad12">
                    </script>
                    <script type="text/javascript">
                        function cvvSuccess() {
                        //display "payment successfully initiated" page
                        }
                    </script>
                

3.2 Inline widget

Inline widget is a modification of the pop-up widget. It does not contain the header with shop name and purchase amount and uses some additional parameters.
1. The widget is displayed inline if the page includes the following element:
<div id="payu-widget"></div>
2. Inline widget can either HTTP POST the output or provide it via a callback function. To use the callback instead of POST, simply add success-callback parameter. The callback function may look like below (it will allow you to see widget's output in your browser's console):
<script>
      function test($data) {
           console.log("callback");
           console.log($data);
      }
</script>
        
3. To display the widget, include the PayU widget bootstrap JS script. Define all the parameters according to your needs. Below example will display a white-background widget without PayU branding and "Use" button (instead of "Pay"). To check what it displays simply copy&paste the below script into the body of your page along with div element and callback function provided above.
                    <script
                        src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                        merchant-pos-id="145227"
                        shop-name="TEST"
                        total-amount="12345"
                        currency-code="PLN"
                        customer-language="en"
                        store-card="true"
                        payu-brand="false"
                        success-callback="test"
                        widget-mode="use"
                        customer-email="test@test.com"
                        sig="203ec8c4b9571ce6b4c03058f57264f04d06d00a86da19390d47ba1be4551578"
                    </script>
                
4. Calculate the SIG parameter necessary to secure communication. Widget parameters and SIG algorithm: Widget parameters.

3.3 Parameters

Calculate the SIG parameter necessary to secure communication. SIG is calculated in the following way:

  1. Sort the parameters required to calculate the SIG alphabetically.
  2. Concatenate the values of parameters taken to the SIG calculation respecting the alphabetical order of the parameters.
  3. Add the value of a private key - visible in POS configuration in the Merchant Control Panel as "Second key (MD5)".
  4. Perform SHA256 function on the whole sequence.
  5. Use the output of the SHA256 function as the "sig" parameter and send it together with other widget parameters.

Example

Parameters need to be sorted alphabetically:

  1. currency-code: EUR
  2. customer-email: test@test.com
  3. customer-language: en
  4. merchant-pos-id: 145227
  5. shop-name: TEST
  6. total-amount: 12345

Then you need to concatenate the values to get a string like below:

EURtest@test.comen145227TEST12345

and add to it the second private key (the example uses a production test POS key value). The final concatenation is:

EURtest@test.comen145227TEST1234513a980d4f851f3d9a1cfc792fb1f5e50

After SHA256 function is performed, we get the sig value:

6dc0247030fa2da54754517586ce02a905e1ff2a21181105174dccec5e291789

Widget script parameters:

Parameter name Required Required for SIG Description
pay-button yes no CSS selector of the payment button
merchant-pos-id yes yes Id of a POS which will be used to create a payment
shop-name yes yes Name of a shop displayed to the Payer inside the widget
total-amount yes yes Total amount of payment displayed to the Payer
currency-code yes yes Payment currency displayed to the Payer, must match the POS currency
customer-language yes yes Language in which the widget will be displayed to the Payer. If the language parameter is missing or is incorrect, the default one - obtained from the Payer's browser configuration - will be used. Available parameters: cs, de, en, es, fr, it, pl, pt.
customer-email no yes Payer's email
widget-type no no Optional value used for selecting type of widget. By default, the widget presents a card form. Provide a cvv value if you want to show the CVV widget.
store-card no yes Values: true/false (default: "false"). Enables multi-use tokens. Required for storing a token.
recurring-payment no yes Values: true/false (default: "false"). Displays a recurring version of the Widget. Requires the storecard parameter set to "true".
payu-brand no yes Values: true/false (default: "true"). Displays widget without PayU branding (only for inline widget).
widget-mode no yes Values: pay/use (default: "pay"). Configures widget buttons. "Pay" mode assumes payment to happen immediately after the widget is used. "Use" mode allows to capture card data without immediate payment.
success-callback no no Name of the callback function which will handle widget's output.
sig yes no Value of a signature providing secure communication.
CVV widget parameters:
Parameter name Required Required for SIG Description
merchant-pos-id yes yes Id of a POS which will be used to create a payment.
shop-name yes yes Name of a shop displayed to the Payer inside the widget.
total-amount yes yes Total amount of payment displayed to the Payer
currency-code yes yes Payment currency displayed to the Payer, must match the POS currency.
customer-language yes yes Language in which the widget will be displayed to the Payer. If the language parameter is missing or is incorrect, the default one - obtained from the Payer's browser configuration - will be used.
widget-type yes no Optional value used for selecting type of widget. By default, the widget presents a card form. Provide a cvv value if you want to show the CVV widget.
cvv-url yes yes CVV URL taken from redirectUri from OrderCreateResponse (when statusCode == WARNING_CONTINUE_CVV) or the query string parameter (refReqId=...) taken from continueUrl after a successful response from the bank (when 3DS was required).
cvv-success-callback no no Callback function executed on successful authorization after the Payer has provided a CVV.
sig yes no Value of a signature providing secure communication.

4 Form

4.1 Card data form

Include the OpenPayU scripts that enable the secure card data transfer to the PayU system:
                    <script src="https://secure.payu.com/res/v2/openpayu-2.1.js"></script>
                    <script src="https://secure.payu.com/res/v2/plugin-token-2.1.js"></script>
                

Create the credit card payment form in a way that the scripts are able to retrieve the correct information. To achieve the desired result, add "input" elements to your page with "class" attributes named as in the example below.

Note: it is unnecessary to embed the "input" elements in a "form" element as the card data should not be sent to your server.

In case you want to send the data and fell under the full scope of PCI DSS compliance, please check Card on file section.

    
                        <table>
                            <tr>
                                <td>card number</td>
                                <td><input type="text" class="payu-card-number"></td>
                            </tr>
                            <tr>
                                <td>card cvv</td>
                                <td><input type="text" class="payu-card-cvv"></td>
                            </tr>
                            <tr>
                                <td>exp month</td>
                                <td><input type="text" class="payu-card-expm"></td>
                            </tr>
                            <tr>
                                <td>exp year</td>
                                <td><input type="text" class="payu-card-expy"></td>
                            </tr>
                            <tr>
                                <td>PayU terms of condition and acceptance to save credit card</td>
                                <td><input type="checkbox" value="false" class="payu-agreement"></td>
                            </tr>                            
                            <input type="hidden" class="payu-customer-email" value="...@...">
                                <tr>
                                    <td><input type="submit" id="payu-cc-form-submit"></td>
                                </tr>
                        </table>                          
           

The scripts searches the page for the following class names:

Class name Required Description
payu-card-cardholder optional cardholder name
payu-card-number yes card number (PAN)
payu-card-cvv yes CVV2/CVC2 code of the card
payu-card-expm yes card expiration month
payu-card-expy yes card expiration year
payu-agreement yes value true/false. Means that the cardholder agreed to save credit card and accepted PayU Account Terms and Conditions. If the value is false PayU will not return multi-use token.
payu-customer-email optional cardholder email address

Add a script handling card tokenization:
    (function () {
        var button = document.querySelector('#payu-cc-form-submit');
        button.addEventListener('click', function (event) {
            OpenPayU.merchantId = 'your POS ID';
            var result = OpenPayU.Token.create({}, function (data) {
                // handle tokenization response, see status code table below
            });
            if (!result) {
                // tokenization request has not been submitted, 
                // check "result" object for validation errors
            }
        }, false);
    })();           
On successful tokenization, the "result" object has value of true and the below objects are passed to callback function. The token property should be passed to your back-end and included in the OrderCreateRequest (see Charging tokens section).
            
         {
           	data: {
           		mask: "444433******1111",
           		token: "TOK_1JKQSX1FMNTU831B8a6z4LDHbzsv",
           		type: "STANDARD"
           	},
           	status: {
           		statusCode: "SUCCESS",
           		codeLiteral: "SUCCESS",
           		code: "0"
           	}
         }        
In case of validation errors, the "result" contains all or one of the following:
            {
               card.expirationDate: "formatInvalid",
               card.expirationMonth: "formatInvalid",
               card.expirationYear: "formatInvalid",
               card.number: "unsupportedType"
            }           

Status codes returned in response to tokenization request are outlined below:

Code Status code Code literal Description
0 SUCCESS SUCCESS Successful tokenization, "data" object returned.
100 ERROR_INTERNAL GENERAL_ERROR Other error.
101 ERROR_UNKNOWN_MERCHANT_POS UNKNOWN_MERCHANT Incorrect POS ID.
4003 ERROR_VALUE_INVALID CARD_INVALID_CVV CVV length is incorrect (only 3 or 4 digits allowed).
4100 SERVICE_NOT_AVAILABLE CARD_TOKENIZATION_DISABLED Tokenization is not enabled for your POS ID.
4101 SERVICE_NOT_AVAILABLE CARD_MERCHANT_INACTIVE Card payments not enabled for your POS ID.

Device fingerprint

A device fingerprint is information collected about a remote computing device for the purpose of identification. Fingerprints can fully or partially identify devices or individual users

Fingerprint value is generated by fingerprint2.js, which must be included to your page.

Usage:
new Fingerprint2({
    excludeJsFonts: true,
    excludeAdBlock: true,
    excludeFlashFonts: true,
    excludeWebGL: true
}).get(function (result) {  //insert callback function here 
});                
Hash generated for this browser: [generateFingerPrint2]

The hash value should be passed to PayU in OrderCreateRequest body, see example below.

4.2 CVV only form

Your front-end should be also able to handle CVV2-only submission.
The following input element should be displayed and filled by the payer:
<input type="text" class="payu-card-cvv">

CVV2 may need to be collected in case it is needed to authenticate payment with a previously tokenized card.

There are 2 cases to handle:

  1. Subsequent charge of a saved card token with full authentication. CVV2 needs to be collected when the payer returns to your page after 3DS authentication - status code WARNING_CONTINUE_CVV is provided in query string added to continueUrl provided in OrderCreateRequest. Query string example:
    ?statusCode=WARNING_CONTINUE_CVV&refReqId=b20399775cbf48a00469280499bdd912
    Script example to handle this scenario (the below code should be triggered after the payer clicked a button to submit the CVV2):
                                var url = "refReqId=" + 'refReqId value from query string';
                                var options = {url: url};
                                OpenPayU.authorizeCVV(options, function(data) {
                                    if (data.status === 'SUCCESS') {
                                        // CVV2 submitted correctly, hide input field
                                    } else {
                                        // handle error (see table above)
                                    }
                                }); 
                            
  2. Subsequent charge of a saved card token with partial (CVV2 only) authentication. Status code WARNING_CONTINUE_CVV is provided in response to OrderCreateRequest. To see response example Charging tokens section. Script example to handle this scenario (the below code should be triggered after the payer clicked a button to submit the CVV2):
                           var options = {url: 'redirectUri value from OrderCreateResponse'};
                           OpenPayU.authorizeCVV(options, function(data) {
                                if (data.status === 'SUCCESS') {
                                        // CVV2 submitted correctly, hide input field
                                    } else {
                                        // handle error (see table above)
                                }
                           });     
                        

5 Charging tokens

Modifying back-end

Order involving REST API is described in: Creating a new order. The payMethods section is the extension. Buyer section is required, also card tokenizaton payMethod must be clearly stated.

Sample PayU | Express order:

                    curl -v -X POST https://secure.payu.com/api/v2_1/orders \
                    -H "Content-Type: application/json" \
                    -H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
                    -d '{
                          "notifyUrl":"https://your.eshop.com/notify",
                          "customerIp":"127.0.0.1",
                          "merchantPosId":"145227",
                          "description":"Laptop",
                          "currencyCode":"PLN",
                          "totalAmount":"15000",
                          "extOrderId":"[generateExtOrderId]",
                          "products":[
                             {
                                "name":     "Laptop",
                                "unitPrice":"15000",
                                "quantity": "1"
                             }
                          ],
                          "buyer": {
                              "email": "john.doe@example.com",
                              "firstName": "John",
                              "lastName": "Doe",
                              "language": "en"
                          },
                          "payMethods": {
                              "payMethod": {
                                   "value": "TOK_1IHRPT6HKSSS3H62K0GS8pElP862",
                                   "type":  "CARD_TOKEN"
                              }
                          },
                          "deviceFingerprint": "[generateFingerPrint2]"
                      }'
                

Authentication methods are described in: Signing API calls parameters.

POS used in the example does not have tokenization switched on.

Order Create Responses:

Example for SUCCESS response with multi-use token:
{
     "orderId": "ORDER_ID",
     "payMethods": {
        "payMethod": {
            "card": {
                "number": "424242******4242",
                "expirationMonth": "12",
                "expirationYear": "2017"
            },
            "type": "CARD_TOKEN",
            "value": "TOKC_KPNZVSLJUNR4DHF5NPVKDPJGMX7"
        }
     },
     "status": {
        "statusCode": "SUCCESS",
        "statusDesc": "Request successful"
     }
}
            
Example for WARNING_CONTINUE_3DS response:
{
     "orderId": "ORDER_ID",
     "status": {
         "statusCode": "WARNING_CONTINUE_3DS",
         "severity": "WARNING"
     },
     "redirectUri": "{redirectUri}"
}
            
Example for WARNING_CONTINUE_CVV response:
{
     "orderId": "ORDER_ID",
     "status": {
         "statusCode": "WARNING_CONTINUE_CVV",
         "severity": "WARNING"
     },
     "redirectUri": "{redirectUri}"
}
            

PayU informs the Shop about the payment by submitting a notification to the address provided in the order in the notifyUrl parameter. To learn more about notifications, read Notifications.

6 Retrieving tokens

Payment methods retrieve service description

Payment methods available for a given user should not be stored locally on merchant's server, but rather retrieved from PayU system for each payment. Retrieved are both the stored (tokenized) payments methods and generic payment methods. Using the retrieve service gives the following benefits:

- only payment methods available at the moment for the user are provided,

- payment methods stored for the user are always up to date and synchronized with user's active PayU Account.

In order to retrieve the payment methods, you need first to obtain OAuth access token.

Obtaining OAuth access token

To obtain OAuth access token, use the POST method to send request to endpoint /pl/standard/user/oauth/authorize.

apiary

Sample request:

curl -X POST https://secure.payu.com/pl/standard/user/oauth/authorize \
   -H "Cache-Control: no-cache" 
   -H "Content-Type: application/x-www-form-urlencoded" 
   -d 'grant_type=trusted_merchant&client_id=[provided by PayU]&client_secret=[provided by PayU]&email=[users email]&ext_customer_id=[Id of the customer used in merchant system]' 

                
Sample positive response (HTTP 200):
{
    "access_token": "4099c2c3-276f-488a-90e2-32620ac441dc",
    "token_type": "bearer",
    "expires_in": 43199,
    "grant_type": "trusted_merchant"
}
            

Retrieving payment methods

Insert the access token into header and use the GET method to send request to endpoint api/v2_1/paymethods .

apiary

Sample request:
curl -X GET https://secure.payu.com/api/v2_1/paymethods \
   -H "Authorization: Bearer 87ad751f-7ea5-4023-a16f-04b6647a07f5" 
   -H "Cache-Control: no-cache" 

                

Sample postive response (HTTP 200). Description of fields are below the sample:

{  
   "cardTokens":[  
      {  
         "cardExpirationYear":"2017",
         "cardExpirationMonth":"12",
         "cardNumberMasked":"411111******1111",
         "cardBrand":"VISA",
         "value":"TOKC_XATB7DF8ACXYTVQIPLWTVPFRKQE",
         "brandImageUrl":"http://static.payu.com/images/mobile/visa.png",
         "preferred":true,
         "status":"ACTIVE"
      },
      {  
         "cardExpirationYear":"2014",
         "cardExpirationMonth":"12",
         "cardNumberMasked":"424242******4242",
         "cardBrand":"VISA",
         "value":"TOKC_XATB7DF8ACXYTVQIPLWTVPFRKQE",
         "brandImageUrl":"http://static.payu.com/images/mobile/visa.png",
         "preferred":false,
         "status":"EXPIRED"
      }
   ],
   "pexTokens":[  
      {  
         "accountNumber":"5311...7744",
         "payType":"mtex",
         "value":"TOKE_XPJ4UKJGHVRPMQPGB6X1JJQCUSS",
         "name":"account name set by the user",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pex_mbank.png",
         "preferred":false,
         "status":"ACTIVE"
      }
   ],
   "payByLinks":[  
      {  
         "value":"c",
         "name":"Płatność online kartą płatniczą",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pbl_c.png",
         "status":"ENABLED"
         "minAmount": 50,
         "maxAmount": 100000
      },
      {  
         "value":"o",
         "name":"Pekao24Przelew",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pbl_o.png",
         "status":"DISABLED"
         "minAmount": 50,
         "maxAmount": 100000
      },
      {  
         "value":"ab",
         "name":"Płacę z Alior Bankiem",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pbl_ab.png",
         "status":"TEMPORARY_DISABLED"
         "minAmount": 50,
         "maxAmount": 100000
      }
   ]
}          
            

cardTokens

This section will be returned empty if the user does not have any active or expired card tokens.
Parameter Description
cardExpirationYear YYYY
cardExpirationMonth MM
cardNumberMasked First 6 and last 4 digits of the PAN (card number).
cardBrand Possible values: 'VISA', 'MASTERCARD', 'MAESTRO'. Other card types are not supported, moreover 'MAESTRO' is not supported in recurring payments. VISA describes various Visa card brands, incl. Visa Electron. MASTERCARD also includes MasterCard Debit.
value Card token value.
brandImageUrl Link to card brand graphic on PayU server.
preferred true/false; it is set to 'true' for a cardToken or bankToken used most recently by the user.
status Possible values: 'ACTIVE' and 'EXPIRED'. 'EXPIRED' tokens may be skipped or presented to the user with a prompt to update or add a new card.If a token has been closed by the user or blocked for security reasons by PayU, it will not be provided in retrieve response.

pexTokens

This section will be returned empty if the user does not have any active pexTokens.

pexTokens relate to bank accounts tokenized through PayU|Express service.

Parameter Description
accountNumber First and last 4 digits of the bank account in the IBAN format.
payType Represents payType of the token.
name Name of the bank account set by the user.
value Bank token value.
brandImageUrl Link to bank logo graphic on PayU server.
preferred true/false; it is set to 'true' for a cardToken or bankToken used most recently by the user.
status Possible value: 'ACTIVE'. If a token has been closed by the user or blocked for security reasons by PayU, it will not be provided in retrieve response. If payType of the token is not configured on merchant's POS, the token will not be provided.

payByLinks

payByLinks are payment methods which always require redirection of the user. Therefore this section includes online bank transfers (pay-by-links), traditional bank transfer, installments and non-tokenized cards.
Parameter Description
value payType value. Available values are here.
name Name of payType set by PayU
brandImageUrl Link to payType logo graphic on PayU server.
status Possible values: 'ENABLED', 'DISABLED', 'TEMPORARY_DISABLED'.

7 Deleting tokens

Deleting a payment token

In case the buyer terminates the user account in your shop or chooses to remove the stored card from the user account, you need to delete the token.

In order to do it, simply send a DELETE message to https://secure.payu.com/api/v2_1/tokens/{tokenValue}

The header should contain a trusted.merchant OAuth token.

For example:
curl -X DELETE https://secure.payu.com/api/v2_1/tokens/TOKC_XATB7DF8ACXYTVQIPLWTVPFRKQE \
   -H "Authorization: Bearer cccbbc40-8113-443b-b4ea-c4b266272b22" 
   -H "Cache-Control: no-cache" 
            

8 Card on file

Card on file (Plain card data):

Order involving REST API is described in: Creating a new order. payMethods section is the extension to the standard OrderCreateRequest. Additionally you need to add "cardOnFile" parameter as in below example.

Note: first transaction (Order) has "cardOnFile" parameter set as "FIRST". Next Orders has "cardOnFile" parameter set as "STANDARD_CARDHOLDER" or "STANDARD_MERCHANT".

"STANDARD_CARDHOLDER" means transaction initiated by the cardholder, whereas "STANDARD_MERCHANT" means transaction initiated by the merchant. At least one payment "FIRST" for three: POS, card, extUserID, must have positive authorization, in order for next payments ("STANDARD_CARDHOLDER" or "STANDARD_MERCHANT") not to require CVV/3DS.

Additionally, in case of response with WARNING_CONTINUE_3DS the payer must be redirected to card issuer website for authentication via 3D Secure. For details please refer to Order Create Responses section in: Charging tokens.

Sample order with cardOnFile flag.

                    curl -v -X POST https://secure.payu.com/api/v2_1/orders \
                    -H "Content-Type: application/json" \
                    -H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
                    -d '{
                         "notifyUrl":"https://your.eshop.com/notify",
                         "customerIp":"127.0.0.1",
                         "merchantPosId":"145227",
                         "cardOnFile": "FIRST", 
                         "description":"Laptop",
                         "currencyCode":"PLN",
                         "totalAmount":"15000",
                         "extOrderId":"[generateExtOrderId]",
                         "products":[
                            {
                               "name":"Laptop",
                               "unitPrice":"15000",
                               "quantity":"1"
                            }
                         ],
                         "buyer": {
                            "email": "john.doe@example.com",
                            "firstName": "John",
                            "lastName": "Doe",
                            "language": "en",
                            "extCustomerId": "1001"
                         },                          
                         "payMethods": {
                            "payMethod": {
                               "card": {
                                  "number":"5100052384536818",
                                  "expirationMonth":"11",
                                  "expirationYear":"2020",
                                  "cvv":"123"
                               }
                            }
                         },
                         "deviceFingerprint": "[generateFingerPrint2]"
                    }'
                

Authentication methods are described in: Signing API calls parameters.

POS used in the example is not configured at PayU side.

9 Payment flows

Below you can find a handy reference of all PayU|Express flow types.

9.1 First charge

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Collect full card data (PAN, expiry date, CVV2/CVC2) via widget or form. Retrieve card token.
  4. Prepare OrderCreateRequest, insert one-time card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  5. Handle the WARNING_CONTINUE_3DS status provided in OrderCreateResponse by redirecting the user to redirectUri provided in the response.
  6. Optionally, only when 3DS authentication took too long and CVV2/CVC2 is no longer cached by PayU: handle the WARNING_CONTINUE_CVV status added to continueUrl.
  7. Receive notification with order status sent to address specfied by you in notifyUrl.
  8. Optionally, only when you do not have auto-receive enabled for the given payment method: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.

9.2 Subsequent charge without card authentication

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods, including multi-use card token. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Prepare OrderCreateRequest, insert multi-use card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  4. Receive notification with order status sent to address specfied by you in notifyUrl.
  5. Optionally, only when you do not have auto-receive enabled on your POS: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.

9.3 Subsequent charge with full card authentication

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods, including multi-use card token. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Prepare OrderCreateRequest, insert multi-use card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  4. Handle the WARNING_CONTINUE_3DS status provided in OrderCreateResponse by redirecting the user to redirectUri provided in the response.
  5. Handle the WARNING_CONTINUE_CVV status added to continueUrl.
  6. Receive notification with order status sent to address specfied by you in notifyUrl.
  7. Optionally, only when you do not have auto-receive enabled on your POS: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.

9.4 Subsequent charge with partial card authentication

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods, including multi-use card token. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Prepare OrderCreateRequest, insert multi-use card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  4. Handle the WARNING_CONTINUE_3DS or WARNING_CONTINUE_CVV status provided in OrderCreateResponse.
  5. Receive notification with order status sent to address specfied by you in notifyUrl.
  6. Optionally, only when you do not have auto-receive enabled on your POS: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.