Automatic Live Update v2 documentation

Last update: Jan 28th, 2014

Summary

  1. Introduction
  2. How does it work?
  3. How to create a request?
  4. The response
  5. Return codes/messages in case of failed requests
  6. Resources

1. Introduction

ALU, short for Automatic Live Update, is intended for merchants who want to place transactions directly in the PayU system. The main advantage that ALU presents is that it allows the Merchant to also send the Shopper card data.

This approach allows merchants full control over their shoppers' experience, meaning that ALU:

2. How does it work?

ALU allows the Merchant to create transactions, using a Server to Server communication with PayU.

The process requires the Merchant to create a request using HTTPs POST protocol, at the following URL: https://secure.payu.ro/order/alu/v2.

The entire flow is depicted in the diagrams bellow.

A. ALU flow for Non 3D Secure enrolled cards

Step 1
When the Shopper decides to pay for the products, he clicks the "Pay" button and the Merchant will collect the data submitted in the form from his shop. This can be saved as a new order in the Merchant system.

Step 2
Merchant system sends the data collected by his shop using an ALU request via HTTP POST from his server to PayU server. The creation of ALU request is detailed here.

Step 3
The PayU Server returns an ALU response inline as a XML document to Merchant's backend. The ALU response is detailed here.

Step 4
Merchant backend matches the ALU response with ALU request and displays the customized results to the Shopper.

B. ALU flow for 3D Secure enrolled cards

Step 1
When a Shopper decides to pay for the products (through his browser), he clicks the "Pay" button and the Merchant will collect the data submitted in the form from his shop. This can be saved as a new order in the Merchant system.

Step 2
Merchant system sends the data collected by his shop using an ALU request via HTTP POST from his server to PayU server. The creation of ALU request is detailed here.

Step 3
PayU identifies that the Shopper has a 3D Secure enrolled card and returns an ALU response inline as a XML document. A sample of the 3DS ALU response can be found here.

Step 4
The Merchant starts the 3DS payment using the URL from the 3DS ALU response.

Steps 5 and 6
The Shopper is redirected to the PayU Server, which redirects him further to the Bank.

Steps 7 and 8
The Bank presents the 3DS form to the Shopper and here can submit his 3DS credentials (password).

Step 9
If the Shopper's 3DS password is correct, the Bank approves the payment. Based on this information, PayU authorizes the payment.

Step 10
PayU sends an ALU response via HTTP POST to BACK_REF URL provided by the Merchant. The POST contains REFNO, ALIAS, STATUS, RETURN_CODE, RETURN_MESSAGE and DATE parameters. Details can be found here.

Step 11
The Merchant backend matches the ALU response with ALU request and displays the customized results to the Shopper.


3. How to create a request?

To use ALU, the Merchant needs to create a HTTP POST request and send it from their server (backend) at the following URL: https://secure.payu.ro/order/alu/v2

The HTTP POST request must contain, at least, the required parameters detailed below.

This method gives the Merchant absolute control over the technology used on their backend to create and send the HTTP POST request, as long it contains the required parameters.

A. Required Parameters List

Order Details
Parameter Description
MERCHANT The Merchant's ID, available in Control Panel (Account Management / Account Settings)
ORDER_REF Order external reference number in Merchant's system
ORDER_DATE The date when the order is initiated in the system, in YYYY-MM-DD HH:MM:SS format (e.g.: "2012-05-01 21:15:45")
Important: Date should be UTC standard +/-10 minutes
PAY_METHOD Payment method for the order. Possible values: CCVISAMC - Visa/Mastercard credit card (default)
ORDER_HASH HMAC_MD5 signature applied on all parameters from the request.
Source string for HMAC_MD5 will be calculated by adding the length of each field value at the beginning of field value. A common key shared between PayU and the merchant is used for the signature. Find more details on how is HASH generated here.
BACK_REF Return URL on the Merchant webshop side that will be used in case of 3DS enrolled cards authorizations.
Product Details
Parameter Description
ORDER_PNAME[] Array filled with the product names (minimum length: 2 characters - maximum length: 155 characters / per product name)
ORDER_PCODE[] Array filled with the product codes (maximum length: 50 characters per product code). If multiple products are sent (in the same or subsequent transactions) with the same product code, PayU will update the product with the corresponding ORDER_PCODE[] (overwriting all the other product information - name, price, taxes).
ORDER_PRICE[] Array filled with unit prices for ordered products. Default currency is set by PRICES_CURRENCY, described below.
ORDER_VAT[] Array with VAT values for each product in the order.
ORDER_PRICE_TYPE[] Array that specifies if the ORDER_PRICE[] includes the VAT. Possible values: "GROSS" (VAT included) and "NET" (VAT will be added by PayU). The parameter is optional, but if not specified, the default value is "NET" . Please note that using "NET" and ORDER_VAT[] different from 0 is deprecated and will be removed in the future.
ORDER_QTY[] Array filled with the ordered quantities for all ordered products.
PRICES_CURRENCY The currency in which the prices are expressed, for example TRY
If the parameter is not specified, the default value is the default currency of the Merchant.
Billing Details
Parameter Description
BILL_LNAME Shopper's last name
BILL_FNAME Shopper's first name
BILL_EMAIL Email address of the Shopper
BILL_PHONE Shopper's phone number
BILL_COUNTRYCODE Shopper's country code in two letters, ISO format
 
Card Details
Parameter Description
CC_NUMBER The card number on which the order authorization will be made.
EXP_MONTH The month in which the card used expires
EXP_YEAR The year in which the card used expires
CC_CVV The CCV/CVV2 code for the card. For some card types this is can be empty, otherwise it should have a numerical value.
CC_OWNER The card owner name, as it appears on the card.

B. Optional Parameters List

Order Details
Parameter Description
ORDER_PINFO[] Array filled with additional product information
ORDER_VER[] Array filled with the product version for all ordered products
SELECTED_INSTALLMENTS_NUMBER The number of installments. It can be an integer between 1 and 12.
CARD_PROGRAM_NAME The name of card program that allows paying an order using installments.
ORDER_TIMEOUT The time in seconds after which the order will expire.
USE_LOYALTY_POINTS A string with value YES. The order will be paid using loyalty points. It can be used for one time payments and (only when the LOYALTY_POINTS_AMOUNT parameter is set and smaller than order total amount) also for installments payments.
LOYALTY_POINTS_AMOUNT Indicates the money amount worth of loyalty points to be used for payment. It can be used only together with USE_LOYALTY_POINTS parameter (set to YES).
It can be an integer that will represent the money amount.
Please note that in case of Garanti cards, you can optionaly send array, since the parameter supports multiple loyalty programs (BNS or FBB), but if you decide to sent an integer value, the system will default on the BNS program:
E.g using integer:
LOYALTY_POINTS_AMOUNT = 16
E.g using array:
LOYALTY_POINTS_AMOUNT[FBB] = 12;
LOYALTY_POINTS_AMOUNT[BNS] = 13.
The value that you are sending (or the sum of values in the case of an array) should be less or equal to the money amount worth of loyalty points which you have available at the bank, otherwise, you will receive an error and the order will not be authorized.
CAMPAIGN_TYPE A predefined string value indicating the type of campaign to be used. It can only have one of the following values: EXTRA_INSTALLMENTS or DELAY_INSTALLMENTS.
For bank terminals supporting both campaign types used at the same time, you can set both comma separated values, e.g: EXTRA_INSTALLMENTS,DELAY_INSTALLMENTS.
Must be used only with installments transactions (the SELECTED_INSTALLMENTS_NUMBER parameter must be greater than or equal to 2).
ORDER_SHIPPING A positive number indicating the price of shipping. The currency is set by PRICES_CURRENCY.
Billing Details
Parameter Description
BILL_FAX Shopper's fax number.
BILL_ADDRESS Shopper's address.
BILL_ADDRESS2 Shopper's address (second line).
BILL_ZIPCODE Address zip code.
BILL_CITY City.
BILL_STATE State / Dept.
Delivery Details
Parameter Description
DELIVERY_LNAME Last name of the person where the order will be delivered
DELIVERY_FNAME First name of the person where the order will be delivered
DELIVERY_EMAIL Email address of the person or company where the order will be delivered
DELIVERY_PHONE The phone of the person of company where the order will be delivered.
DELIVERY_COMPANY Company name where the order will be delivered.
DELIVERY_ADDRESS Oder delivery address.
DELIVERY_ADDRESS2 More details on order delivery address.
DELIVERY_ZIPCODE Order delivery address zip code.
DELIVERY_CITY Order delivery city.
DELIVERY_STATE Order delivery state.
DELIVERY_COUNTRYCODE Delivery country code in two letters ISO format.
Details for antifraud
Parameter Description
CC_NUMBER_TIME Time spent by user to insert card number
CC_OWNER_TIME Time spent by user to insert card owner
Airline Information

The airline information parameter, AIRLINE_INFO, should be provided by any airline services operator merchant. This parameter contains basic information about the passenger and his/her flight ticket.

Parameter Description Required
PASSENGER_NAME First name and last name of the passenger (max. 20 characters) Yes
TICKET_NUMBER Ticket number (max. 14 characters) No
RESTRICTED_REFUND Possibility of refund (0 - no restrictions, 1 - non refundable) No
RESERVATION_SYSTEM Name of reservation system (e.g. ATS = Delta, SABR = Sabre) (max. 4 characters) No
TRAVEL_AGENCY_CODE The code of travel agency (max. 8 characters) No
TRAVEL_AGENCY_NAME The name of travel agency (max. 25 characters) No
FLIGHT_SEGMENTS

An array containing information about this flight transits. First element should have 0 as key, second should have 1 as key etc. The structure of these elements is defined below:

Parameter Description Required
DEPARTURE_DATE Departure date in the format YYYY-MM-DD Yes
DEPARTURE_AIRPORT Departure airport code (max. 3 characters) Yes
DESTINATION_AIRPORT Destination airport code (max. 3 characters) Yes
AIRLINE_CODE Airline 2-letters code No
AIRLINE_NAME Airline name ((max. 20 characters)) No
SERVICE_CLASS Ticket type (class) (economy, business class, etc.) (max. 1 char) No
STOPOVER Displays the possibility of stop-over for the given ticket; 1 = Stop-over is allowed, 0 - not allowed No
FARE_CODE Tariff code (max. 6 characters) No
FLIGHT_NUMBER Flight number (max. 5 characters) No

For instance, the DEPARTURE_DATE of first flight transit/segment would be referenced as the POST variable AIRLINE_INFO[FLIGHT_SEGMENTS][0][DEPARTURE_DATE].

Yes
Other Details
Parameter Description
CLIENT_IP IP address of the Shopper
CLIENT_TIME Time collected from the Shopper's browser in YYYY-MM-DD hh:mm;ss format
 

B. ORDER_HASH calculation

For security reason, each HTTP POST request must carry a unique signature. The signature is calculated using data from all parameters sent in the HTTP POST, the Merchant's secret key and the HMAC MD5 algorithm to encrypt data (RFC 2104).

For example, let's consider that a Merchant (OPU_TEST with secret key SECRET_KEY) sends the HTTP POST request to ALU containing the following parameters and values:
			"MERCHANT" => "OPU_TEST"
			"ORDER_REF" => "7305"
			"ORDER_DATE" => "2013-03-11+13:00:04"
			"ORDER_PNAME[0]" => "Ticket1"
			"ORDER_PCODE[0]" => "TCK1"
			"ORDER_PINFO[0]" => "Barcelona flight"
			"ORDER_PRICE[0]" => "100"
			"ORDER_QTY[0]" => "1"
			"ORDER_PNAME[1]" => "Ticket2"
			"ORDER_PCODE[1]" => "TCK2"
			"ORDER_PINFO[1]" => "London flight"
			"ORDER_PRICE[1]" => "200"
			"ORDER_QTY[1]" => "1"
			"PRICES_CURRENCY" => "TRY"
			"PAY_METHOD" => "CCVISAMC"
			"SELECTED_INSTALLMENTS_NUMBER" => "3"
			"CC_NUMBER" => "4355084355084358"
			"EXP_MONTH" => "01"
			"EXP_YEAR" => "2016"
			"CC_CVV" => "123"
			"CC_OWNER" => "FirstName LastName"
			"BACK_REF" => "https://www.example.com/alu/3ds_return.php"
			"CLIENT_IP" => "127.0.0.1"
			"BILL_LNAME" => "John"
			"BILL_FNAME" => "Doe"
			"BILL_EMAIL" => "shopper@payu.ro"
			"BILL_PHONE" => "1234567890"
			"BILL_COUNTRYCODE" => "TR"
            "DELIVERY_FNAME" => "John"
            "DELIVERY_LNAME" => "Smith"
            "DELIVERY_PHONE" => "0729581297"
            "DELIVERY_ADDRESS" => "3256 Epiphenomenal Avenue"
            "DELIVERY_ZIPCODE" => "55416"
            "DELIVERY_CITY" => "Minneapolis"
            "DELIVERY_STATE" => "Minnesota"
            "DELIVERY_COUNTRYCODE" => "MN"
		
NOTE ORDER_PNAME, ORDER_PCODE, ORDER_PINFO, ORDER_PRICE and ORDER_QTY must be sent in the HTTP POST along with the square brackets "[]".

Step 1: Sort alphabetically all the parameters sent in the HTTP POST by parameter's name

NOTE Parameters should be sorted by their name (key), NOT their values.
Using the example, this is the order of after the sort:
			BACK_REF, BILL_COUNTRYCODE, BILL_EMAIL, BILL_FNAME, BILL_LNAME, BILL_PHONE, CC_CVV, CC_NUMBER, CC_OWNER, CLIENT_IP, DELIVERY_ADDRESS, DELIVERY_CITY, DELIVERY_COUNTRYCODE, DELIVERY_FNAME, DELIVERY_LNAME, DELIVERY_PHONE, DELIVERY_STATE, DELIVERY_ZIPCODE, EXP_MONTH, EXP_YEAR, MERCHANT, ORDER_DATE, ORDER_PCODE[0], ORDER_PCODE[1], ORDER_PINFO[0], ORDER_PINFO[1], ORDER_PNAME[0], ORDER_PNAME[1], ORDER_PRICE[0], ORDER_PRICE[1], ORDER_QTY[0], ORDER_QTY[1], ORDER_REF, PAY_METHOD, PRICES_CURRENCY, SELECTED_INSTALLMENTS_NUMBER
    
IMPORTANT If an order request contains more than one product, the ORDER_PNAME[], ORDER_PCODE[], ORDER_PINFO[], ORDER_PRICE[], ORDER_VER[] and ORDER_QTY[] arrays MUST be synchronized.
NOTE POST parameters which are associative arrays, shouldn't be sorted once again by themselves; instead, you should apply a depth-first parsing of such array for computing the signature; this means that the algorithm starts at the root of array and explores as far as possible along each element before eventually going back to a previous level.

Step 2: Compose the source string by adding the length of each HTTP POST parameter value at the beginning of the HTTP POST parameter value

For example, if the Merchant is OPU_TEST, the composed source will be: 8OPU_TEST (8 is the number of characters in OPU_TEST).

NOTE Before you are actually composing the signature string, strip off all the backslashes from the values: \' becomes ' and so on. Double backslashes (\\) should be translated as a single backslash (\).
NOTE If a HTTP POST parameter is sent empty it has to be added to the source string as 0. For example, if the SELECTED_INSTALLMENTS_NUMBER parameter is sent empty and due to the fact that after sorting, SELECTED_INSTALLMENTS_NUMBER is the last one, 0 should be added at the end of the source string.

Now, based on this, the entire source string for the values of the sorted parameters at Step 1 will be:

			42https://www.example.com/alu/3ds_return.php2TR15shopper@payu.ro3Doe4John101234567890312316435508435508435818FirstName LastName9127.0.0.1253256 Epiphenomenal Avenue11Minneapolis2MN4John5Smith1007295812979Minnesota555416201420168OPU_TEST192013-03-11+13:00:044TCK14TCK216Barcelona flight13London flight7Ticket17Ticket2310032001111473058CCVISAMC3TRY13
    

Step 3: Calculate the HASH using the HMAC MD5 encryption algorithm, the source string (as data) and Merchant's SECRET_KEY (as key)

From the POST we can see that Merchant's secret key in this example is "SECRET_KEY", so the HASH value will be:

			14de52ecc7ca8202bbef94f2471e5768
    

Step 4: Add the calculated HASH value to the HTTP POST request before sending it to PayU

			ORDER_HASH: "14de52ecc7ca8202bbef94f2471e5768"
    
PayU will also calculate the HASH on its side with data received, and it will match it with the HASH sent by the Merchant.

C. 3D Secure

When the Shopper uses a card enrolled in 3D Secure system, PayU will return in response XML, the 3DS_ENROLLED code and URL_3DS url. Using URL_3DS, the merchant should redirect the browser in order for the user to perform 3DS authentication. After the authentication process ends, the Merchant will receive the results via POST to BACK_REF url containing REFNO, ALIAS, STATUS, RETURN_CODE, RETURN_MESSAGE and DATE parameters. Details can be found here.

 

4. The response

The PayU system will respond in the XML format detailed below. The Merchant has to parse and process data from this XML on his backend. In case of 3DS, the same data is sent as HTTP POST to the BACK_REF url. In case if some API limit is defined in PayU system, we also return some specific headers with information about it (see API Limit documentation).

Parameter Description
REFNO Global PayU reference number for the order. This is unique across all requests. If any of the required parameters is missing, this will be empty!
ALIAS Unique string representation of the transaction that can be used by the Merchant in his backend.
STATUS Possible values:
  • SUCCESS - If the payment was authorized. In this case also REFNO is returned (see response sample)
  • FAILED - If the payment could NOT be authorized for various reasons (fraud, insufficient funds etc.). In this case a REFNO is returned, but the payment is Pending (see response sample)
  • INPUT_ERROR - If the payment request has erroneous or missing required parameters (see response sample)
  • ALU_NOT_ALLOWED - If ALU is disabled for this merchant or the maximum number of ALU calls was reached (see response sample)
RETURN_CODE Possible values:
  • AUTHORIZED - If the payment was authorized (see response sample)
  • 3DS_ENROLLED - The payment authorization needs to be confirmed by the Shopper with his BANK using 3DS (see response sample)
  • ALREADY_AUTHORIZED - If the Shopper tries to place a new order with the same ORDER_REF and HASH as a previous one (see response sample).
  • AUTHORIZATION_ALREADY_IN_PROGRESS - An authorization process for the same order is in progress.
  • AUTHORIZATION_FAILED - The payment was NOT authorized (see response sample)
  • INVALID_CUSTOMER_INFO - Required data from the Shopper is missing or if malformed (see response sample)
  • INVALID_PAYMENT_INFO - Card data is NOT correct (see response sample)
  • INVALID_ACCOUNT - The Merchant name is NOT correct (see response sample)
  • INVALID_PAYMENT_METHOD_CODE - Payment method code is NOT recognized (see response sample)
  • INVALID_CURRENCY - Payment currency is NOT recognized (see response sample)
  • REQUEST_EXPIRED - If between ORDER_DATE is and payment date has passed more than 10 minutes or more than ORDER_TIMEOUT set by the merchant (see response sample)
  • HASH_MISMATCH - If HASH sent by the Merchant does NOT match the HASH calculated by PayU (see response sample).
  • WRONG_VERSION - If ALU version sent by the Merchant does NOT exist (see response sample).
  • INSTALLMENTS_LOYALTY_POINTS_INCOMPATIBLE - May appear when USE_LOYALTY_POINTS is set YES and SELECTED_INSTALLMENTS is set to a number greater than 1 (see response sample).
  • LIMIT_EXCEEDED - May appear when the number of ALU requests allowed on platform or merchant level was reached. (see response sample). In this case http response code will be 429.
RETURN_MESSAGE A more detailed description of the response code
DATE Date of the response in UTC format
URL_3DS In case that the credit card is enrolled in 3D Secure system, this parameter will contain an URL where the Merchant should redirect the browser of the Shopper (see response sample).
ORDER_REF Order external reference number in Merchant's system
AUTH_CODE Bank authorization code
RRN Retrieval reference number
HASH Signature applied for the all elements from the request using the same algorithm as the signature from the initial request.
Parameters must be concatenated in the order presented above. URL_3DS is not included in the signature.
If the signature is NOT correct you'll get a HASH_MISMATCH error and the HASH tag will be empty.

Response samples

Below are displayed a few different ALU responses. Sample response for Non 3D Secure enrolled card:
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO>123456789</REFNO>
            <ALIAS>9592b7736c9e277fea8cc79c2e5b5a23</ALIAS>
            <STATUS>SUCCESS</STATUS>
            <RETURN_CODE>AUTHORIZED</RETURN_CODE>
            <RETURN_MESSAGE>Successfull authorized</RETURN_MESSAGE>
            <DATE>2012-11-06 20:52:20</DATE>
            <ORDER_REF>7305</ORDER_REF>
            <AUTH_CODE>13157TUlA15117</AUTH_CODE>
            <HASH>b560a38e2b3e7bcbac328bbd6218bc60</HASH>
        </EPAYMENT>
		
Sample response for 3D Secure enrolled card:
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO>123456789</REFNO>
            <ALIAS>9592b7736c9e277fea8cc79c2e5b5a23</ALIAS>
            <STATUS>SUCCESS</STATUS>
            <RETURN_CODE>3DS_ENROLLED</RETURN_CODE>
            <RETURN_MESSAGE>3DS Enrolled Card.</RETURN_MESSAGE>
            <DATE>2010-12-09 20:44:37</DATE>
            <URL_3DS>https://secure.payu.ro/order/alu_return_3ds.php?request_id=2Xrl85eakbSBr3WtcbixYQ%3D%3D
            </URL_3DS>
            <ORDER_REF>7306</ORDER_REF>
            <AUTH_CODE>465321</AUTH_CODE>
            <HASH>623a8c7e88ccc9b9d4ed3bcd1271e5d5</HASH>
        </EPAYMENT>
		
Sample response for failed card authorisation
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO>6468866</REFNO>
            <ALIAS></ALIAS>
            <STATUS>FAILED</STATUS>
            <RETURN_CODE>AUTHORIZATION_FAILED</RETURN_CODE>
            <RETURN_MESSAGE>Authorization declined</RETURN_MESSAGE>
            <DATE>2013-02-27 17:55:16</DATE>
            <ORDER_REF>7308</ORDER_REF>
            <AUTH_CODE>449322</AUTH_CODE>
            <HASH>b0fb097ecb973316b2740192b655f41e</HASH>
        </EPAYMENT>
		
Sample response for already authorized order
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO>12092863</REFNO>
            <ALIAS></ALIAS>
            <STATUS>FAILED</STATUS>
            <RETURN_CODE>ALREADY_AUTHORIZED</RETURN_CODE>
            <RETURN_MESSAGE>The payment for your order is already authorized.</RETURN_MESSAGE>
            <DATE>2013-02-27 17:55:16</DATE>
            <ORDER_REF>7308</ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH>b0fb097ecb973316b2740192b655f41e</HASH>
        </EPAYMENT>
		
Sample response for erroneous required parameters
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>INVALID_CUSTOMER_INFO</RETURN_CODE>
            <RETURN_MESSAGE>Mandatory billing information missing: Email</RETURN_MESSAGE>
            <DATE>2013-02-27 17:59:56</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for invalid card data
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>INVALID_PAYMENT_INFO</RETURN_CODE>
            <RETURN_MESSAGE>Invalid expiration date entered or the card has expired. (4111111111111111)</RETURN_MESSAGE>
            <DATE>2013-02-27 17:58:55</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for invalid payment method code
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>INVALID_PAYMENT_METHOD_CODE</RETURN_CODE>
            <RETURN_MESSAGE>Invalid payment method for this account: CCVISAMC</RETURN_MESSAGE>
            <DATE>2013-02-27 17:58:01</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for invalid Merchant account name
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>INVALID_ACCOUNT</RETURN_CODE>
            <RETURN_MESSAGE>Invalid account: Brands</RETURN_MESSAGE>
            <DATE>2013-02-27 17:58:23</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for expired request
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>REQUEST_EXPIRED</RETURN_CODE>
            <RETURN_MESSAGE>Your request has expired - it is older than 10 minutes (2011-02-27 16:28:15)!
            </RETURN_MESSAGE>
            <DATE>2013-02-27 18:30:56</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for invalid currency
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>INVALID_CURRENCY</RETURN_CODE>
            <RETURN_MESSAGE>Invalid currency: RDF! Allowed values: UAH, EUR, RUB, USD, BYR, KZT</RETURN_MESSAGE>
            <DATE>2013-02-27 18:28:19</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for HASH mismatch
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>HASH_MISMATCH</RETURN_CODE>
            <RETURN_MESSAGE>Hash mismatch</RETURN_MESSAGE>
            <DATE>2013-02-27 17:56:12</DATE>
            <ORDER_REF></ORDER_REF>
            <AUTH_CODE></AUTH_CODE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for WRONG_VERSION
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>INPUT_ERROR</STATUS>
            <RETURN_CODE>WRONG_VERSION</RETURN_CODE>
            <RETURN_MESSAGE>Wrong version</RETURN_MESSAGE>
            <DATE>2013-06-06 21:26:13</DATE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for Loyalty points with installments incompatibility error
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>FAILED</STATUS>
            <RETURN_CODE>INSTALLMENTS_LOYALTY_POINTS_INCOMPATIBLE</RETURN_CODE>
            <RETURN_MESSAGE>Cannot use installments on orders paid with loyalty points.</RETURN_MESSAGE>
            <DATE>2013-02-27 18:14:49</DATE>
            <HASH></HASH>
        </EPAYMENT>
		
Sample response for ALU calls limit exceeded
		<?xml version="1.0"?>
		<EPAYMENT>
            <REFNO></REFNO>
            <ALIAS></ALIAS>
            <STATUS>ALU_NOT_ALLOWED</STATUS>
            <RETURN_CODE>LIMIT_EXCEEDED</RETURN_CODE>
            <RETURN_MESSAGE>Limit calls for ALU exceeded for this merchant!</RETURN_MESSAGE>
            <DATE>2013-02-27 18:14:49</DATE>
            <HASH></HASH>
        </EPAYMENT>
		
IMPORTANT In case the Merchant has sent more than one order with the same external reference and price, the query will return information for the most recent transaction found in the database for that reference.
 

5. Return codes/messages in case of failed requests

Visa and Mastercard issued new rules prohibiting excessive payment reattempts.
For the below cases reattempts with the same card are not permitted:

CardType Return code Return code translation Action to be taken
MASTERCARD GWERROR_04 Restricted card No retries whatsoever
VISA GWERROR_04 Restricted card No retries whatsoever
MASTERCARD GWERROR_14 No such card No retries whatsoever
VISA GWERROR_14 No such card No retries whatsoever
MASTERCARD GWERROR_57 Transaction not permitted on card No retries whatsoever
VISA GWERROR_57 Transaction not permitted on card No retries whatsoever

Visa and Mastercard issued new rules prohibiting excessive payment reattempts.
For the below cases there is a low chance of a successful authorization, so Visa’s rules broadly prohibit more than 15 retries of a single payment over 30 calendar days and Mastercard new rules broadly prohibit more than 10 retries over a 24 hours period:

CardType Return code Return code translation Action to be taken
MASTERCARD GWERROR_3DS20_SOFT_DECLINE Soft Decline Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_3DS20_SOFT_DECLINE Soft Decline Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_05 Authorization declined Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_05 Authorization declined Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_51 Insufficient funds Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_51 Insufficient funds Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_54 Expired card Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_54 Expired card Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_61 Exceeds amount limit Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_61 Exceeds amount limit Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_62 Restricted card Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_62 Restricted card Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_84 Invalid cvv Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_84 Invalid cvv Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_91 A technical problem occurred. Issuer cannot process Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_91 A technical problem occurred. Issuer cannot process Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_93 Violation of law Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_93 Violation of law Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_96 System malfunction Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_96 System malfunction Limit Reattempt to no more than 15 within a 30 days timeframe
MASTERCARD GWERROR_107 Sorry at the moment the transaction cannot be processed due to ecessive retries with this card. Please try using another card. Limit Reattempt to no more than 10 in a 24 hours timeframe
VISA GWERROR_107 Sorry at the moment the transaction cannot be processed due to ecessive retries with this card. Please try using another card. Limit Reattempt to no more than 15 within a 30 days timeframe

Below is a list of codes/messages that may appear in case of failed transactions (<status>FAILED</status>).

Return code Translation
GW_ERROR_GENERIC An error occurred during processing. Please retry the operation
GW_ERROR_GENERIC_3D An error occurred during 3DS processing
GWERROR_3DS20_SOFT_DECLINE Soft Decline
GWERROR_-19 Authentication failed
GWERROR_-10 Error in amount field
GWERROR_-9 Error in card expiration date field
GWERROR_-8 Invalid card number
GWERROR_-3 Call acquirer support call number
GWERROR_-2 An error occurred during processing. Please retry the operation
GWERROR_01 Card type not active or incorrect PIN
GWERROR_02 Refer to card issuer, special condition
GWERROR_03 Invalid merchant
GWERROR_04 Restricted card
GWERROR_05 Authorization declined
GWERROR_06 Error - retry
GWERROR_07 Password incorrect or card disabled
GWERROR_08 Invalid amount
GWERROR_12 Amount exceeds card ceiling
GWERROR_13 Invalid amount
GWERROR_14 No such card
GWERROR_15 No such card/issuer
GWERROR_17 Customer cancellation
GWERROR_19 Re-enter transaction
GWERROR_20 Invalid response
GWERROR_21 No action taken (unable to back out prior transaction)
GWERROR_22 Suspected Malfunction
GWERROR_25 Unable to locate record in file, or account number is missing from the inquiry
GWERROR_28 File is temporarily unavailable
GWERROR_30 Format error
GWERROR_34 Credit card number failed the fraud
GWERROR_36 Credit restricted
GWERROR_41 Lost card
GWERROR_43 Stolen card, pick up
GWERROR_51 Insufficient funds
GWERROR_53 No savings account
GWERROR_54 Expired card
GWERROR_55 Incorrect PIN
GWERROR_57 Transaction not permitted on card
GWERROR_58 Not permitted to merchant
GWERROR_59 Suspected fraud
GWERROR_61 Exceeds amount limit
GWERROR_62 Restricted card
GWERROR_63 Security violation
GWERROR_65 Exceeds frequency limit
GWERROR_68 Response received too late
GWERROR_75 PIN tries exceeded
GWERROR_78 Reserved
GWERROR_81 PIN cryptographic error found (error found by VIC security module during PIN decryption)
GWERROR_82 Time-out at issuer
GWERROR_83 Unable to verify PIN
GWERROR_84 Invalid cvv
GWERROR_89 Authentication failure
GWERROR_91 A technical problem occurred. Issuer cannot process
GWERROR_92 Router unavailable
GWERROR_93 Violation of law
GWERROR_94 Duplicate transmission
GWERROR_95 Reconcile error
GWERROR_96 System malfunction
GWERROR_98 Error during canceling transaction
GWERROR_99 Incorrect card brand
GWERROR_102 Acquirer timeout
GWERROR_105 3DS authentication error
GWERROR_107 Sorry, at the moment the transaction cannot be processed due to ecessive retries with this card. Please try using another card.
GWERROR_108 Sorry, at the moment the transaction cannot be processed. Please try using another card.
GWERROR_109 Inactive card, please activate the card first.
GWERROR_2204 No permission to process the card installment.
GWERROR_2304 There is an ongoing process your order.
GWERROR_5007 Debit cards only supports 3D operations.
ALREADY_AUTHORIZED Re-enter transaction
NEW_ERROR Message flow error
WRONG_ERROR Re-enter transaction
-9999 Banned operation
1 Call acquirer support call number
 

6. Resources

cURL sample

Using the example presented above, here's the cURL command to ALU.
			curl -L https://secure.payu.ro/order/alu/v2 \
			-d BACK_REF=https%3A%2F%2Fwww.example.com%%2Falu%2F3ds_return.php \
			-d BILL_COUNTRYCODE=TR \
			-d BILL_EMAIL=shopper%40payu.ro \
			-d BILL_FNAME=Doe \
			-d BILL_LNAME=John \
			-d BILL_PHONE=1234567890 \
			-d CC_CVV=123 \
			-d CC_NUMBER=4355084355084358 \
			-d CC_OWNER=FirstName+LastName \
			-d CLIENT_IP=127.0.0.1 \
			-d EXP_MONTH=01 \
			-d EXP_YEAR=2016 \
			-d MERCHANT=OPU_TEST \
			-d ORDER_DATE=2013-03-11+16%3A34%3A02 \
			-d ORDER_PCODE[0]=TCK1 \
			-d ORDER_PCODE[1]=TCK2 \
			-d ORDER_PINFO[0]=Barcelona+flight \
			-d ORDER_PINFO[1]=London+flight \
			-d ORDER_PNAME[0]=Ticket1 \
			-d ORDER_PNAME[1]=Ticket2 \
			-d ORDER_PRICE[0]=100 \
			-d ORDER_PRICE[1]=200 \
			-d ORDER_QTY[0]=1 \
			-d ORDER_QTY[1]=1 \
			-d ORDER_REF=7295 \
			-d DELIVERY_FNAME=John \
			-d DELIVERY_LNAME=Smith \
			-d DELIVERY_PHONE=7295 \
			-d DELIVERY_ADDRESS=3256+Epiphenomenal+Avenue \
			-d DELIVERY_ZIPCODE=55416 \
			-d DELIVERY_CITY=Minneapolis \
			-d DELIVERY_STATE=Minnesota \
			-d DELIVERY_COUNTRYCODE=MN \
			-d PAY_METHOD=CCVISAMC \
			-d PRICES_CURRENCY=TRY \
			-d SELECTED_INSTALLMENTS_NUMBER=3 \
            -d AIRLINE_INFO[PASSENGER_NAME]=Doe+John \ # Start of AIRLINE_INFO param construction
			-d AIRLINE_INFO[TICKET_NUMBER]=1497434371.1006 \
			-d AIRLINE_INFO[FLIGHT_SEGMENTS][0][DEPARTURE_DATE]=2017-06-14 \ # First flight transit
			-d AIRLINE_INFO[FLIGHT_SEGMENTS][0][DEPARTURE_AIRPORT]=ABC \
			-d AIRLINE_INFO[FLIGHT_SEGMENTS][0][DESTINATION_AIRPORT]=CBA \
            -d AIRLINE_INFO[FLIGHT_SEGMENTS][1][DEPARTURE_DATE]=2017-06-20 \ # Second flight transit
			-d AIRLINE_INFO[FLIGHT_SEGMENTS][1][DEPARTURE_AIRPORT]=CBA \
			-d AIRLINE_INFO[FLIGHT_SEGMENTS][1][DESTINATION_AIRPORT]=XYZ \
			-d ORDER_HASH=14de52ecc7ca8202bbef94f2471e5768
    

PHP sample for sending a request to ALU

This PHP sample is a functional server to server request to ALU.
		
		<?php
		$url = "https://secure.payu.ro/order/alu/v2";

		$secretKey = 'SECRET_KEY';
		$arParams = array(
			//The Merchant's ID
			"MERCHANT" => "OPU_TEST",
			//order external reference number in Merchant's system
			"ORDER_REF" => rand(1000,9999),
			"ORDER_DATE" => gmdate('Y-m-d H:i:s'),
			
			//First product details begin
			"ORDER_PNAME[0]" => "Ticket1",
			"ORDER_PCODE[0]" => "TCK1",
			"ORDER_PINFO[0]" => "Barcelona flight",
			"ORDER_PRICE[0]" => "100",
			"ORDER_QTY[0]" => "1",
			//First product details end
			
			//Second product details begin
			"ORDER_PNAME[1]" => "Ticket2",
			"ORDER_PCODE[1]" => "TCK2",
			"ORDER_PINFO[1]" => "London flight",
			"ORDER_PRICE[1]" => "200",
			"ORDER_QTY[1]" => "1",
			//Second product details end

			"PRICES_CURRENCY" => "TRY",
			"PAY_METHOD" => "CCVISAMC",//to remove
			"SELECTED_INSTALLMENTS_NUMBER" => "3",
			"CC_NUMBER" => "4355084355084358",
			"EXP_MONTH" => "01",
			"EXP_YEAR" => "2016",
			"CC_CVV" => "123",
			"CC_OWNER" => "FirstName LastName",
			
			//Return URL on the Merchant webshop side that will be used in case of 3DS enrolled cards authorizations.
			"BACK_REF" => "https://www.example.com/alu/3ds_return.php",
			"CLIENT_IP" => "127.0.0.1",
			"BILL_LNAME" => "John",
			"BILL_FNAME" => "Doe",
			"BILL_EMAIL" => "shopper@payu.ro",
			"BILL_PHONE" => "1234567890",
			"BILL_COUNTRYCODE" => "TR",
            
            //Delivery information
            "DELIVERY_FNAME" => "John",
            "DELIVERY_LNAME" => "Smith",
            "DELIVERY_PHONE" => "0729581297",
            "DELIVERY_ADDRESS" => "3256 Epiphenomenal Avenue",
            "DELIVERY_ZIPCODE" => "55416",
            "DELIVERY_CITY" => "Minneapolis",
            "DELIVERY_STATE" => "Minnesota",
            "DELIVERY_COUNTRYCODE" => "MN",
		);

		//begin HASH calculation
		ksort($arParams);
		
		$hashString = "";

		foreach ($arParams as $key=>$val) {
			$hashString .= strlen($val) . $val;
		}

		$arParams["ORDER_HASH"] = hash_hmac("md5", $hashString, $secretKey);
		//end HASH calculation

		$ch = curl_init();

		curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arParams));

		$response = curl_exec($ch);

		$curlerrcode = curl_errno($ch);
		$curlerr = curl_error($ch);

        curl_close($ch);

		if (empty($curlerr) && empty($curlerrcode)) {
			$parsedXML = @simplexml_load_string($response);
			if ($parsedXML !== FALSE) {

				//Get PayU Transaction reference.
				//Can be stored in your system DB, linked with your current order, for match order in case of 3DSecure enrolled cards
				//Can be empty in case of invalid parameters errors
				$payuTranReference = $parsedXML->REFNO;

				if ($parsedXML->STATUS == "SUCCESS") {

					//In case of 3DS enrolled cards, PayU will return the extra XML tag URL_3DS that contains a unique url for each 
					//transaction. For example https://secure.payu.ro            /order/alu_return_3ds.php?request_id=2Xrl85eakbSBr3WtcbixYQ%3D%3D.
					//The merchant must redirect the browser to this url to allow user to authenticate. 
					//After the authentification process ends the user will be redirected to BACK_REF url
					//with payment result in a HTTP POST request - see 3ds return sample. 
					if (($parsedXML->RETURN_CODE == "3DS_ENROLLED") && (!empty($parsedXML->URL_3DS))) {
						header("Location:" . $parsedXML->URL_3DS);
						die();
					}

					echo "SUCCESS [PayU reference number: " . $payuTranReference . "]";
				} else {
					echo "FAILED: " . $parsedXML->RETURN_MESSAGE . " [" . $parsedXML->RETURN_CODE . "]";
					if (!empty($payuTranReference)) {
						//the transaction was register to PayU system, but some error occured during the bank authorization.
						//See $parsedXML->RETURN_MESSAGE and $parsedXML->RETURN_CODE for details                
						echo " [PayU reference number: " . $payuTranReference . "]";
					}
				}
			}
		} else {
			//Was an error comunication between servers
			echo "cURL error: " . $curlerr;
		}
		?>
		

PHP sample for handling ALU response in case of 3DS return to BACK_REF

		<?php

		if (!isset($_POST['HASH']) || !empty($_POST['HASH'])) {

			//begin HASH verification
			$arParams = $_POST;
			unset($arParams['HASH']);

			$hashString = "";
			foreach ($arParams as $val) {
				$hashString .= strlen($val) . $val;
			}

			$secretKey = 'SECRET_KEY';
			$expectedHash = hash_hmac("md5", $hashString, $secretKey);
			if ($expectedHash != $_POST["HASH"]) {
				echo "FAILED. Hash mismatch";
				die;
			}
			//end hash verification
			
			//Use the information below to match against your database record.
			$payuTranReference = htmlentities($_POST['REFNO']);
			$amount = htmlentities($_POST['AMOUNT']);
			$currency = htmlentities($_POST['CURRENCY']);
			$installments_no = htmlentities($_POST['INSTALLMENTS_NO']);

			if ($_POST['STATUS'] == "SUCCESS") {
				//Update status of the transaction in your database.
				echo "SUCCESS [PayU reference number: " . $payuTranReference . "]";
			} else {
				echo "FAILED ". htmlentities($_POST['RETURN_MESSAGE']) ."[". htmlentities($_POST['RETURN_CODE']) ."]";
				echo " [PayU reference number: " . $payuTranReference . "]";
			}
		} else {
			echo "FAILED. Hash missing";
		}
		?>
		
Document version history
Version Date Change details Change author
2.1.4 January 30th, 2018 The following response codes has been created and/or updated: GWERROR_02, GWERROR_17, GWERROR_21, GWERROR_22, GWERROR_25, GWERROR_28, GWERROR_59, GWERROR_68, GWERROR_81, GWERROR_83 and GWERROR_95. PayU
2.1.3 June 19th, 2017 Added AIRLINE_INFO parameter PayU
2.1.2 Jan 28th, 2014 Usage of loyalty points Ruxandra Laceanu
2.1.1 Jan 14th, 2014 More info on resume order Andrei Olaru
2.1 Sep 30th, 2013 Add delivery details in the examples Alexandru Gurau
2.0 June 7th, 2013 ALU version 2 endpoint; ORDER_REF and AUTH_CODE were added to ALU response; Andrei Olaru
1.2 May 9th, 2013 More details on return codes/messages in case of failed requests Andrei Olaru
1.1 March 1st, 2013 More details on HTTP POST creation and examples Andrei Olaru
1.0 June 1st, 2012 Document creation PayU