3.9. /api/v2/make-rebill-preauth
Introduction
Preauth recurring transactions are initiated through HTTPS POST request to the URLs and the parameters specified below. Use SHA-1 for authentication. See Statuses.
API URLs
| Integration | Production |
|---|---|
| https://sandbox.billblend.com/checkout/api/v2/make-rebill-preauth/ENDPOINTID | https://pay.billblend.com/checkout/api/v2/make-rebill-preauth/ENDPOINTID |
| https://sandbox.billblend.com/checkout/api/v2/make-rebill-preauth/group/ENDPOINTGROUPID | https://pay.billblend.com/checkout/api/v2/make-rebill-preauth/group/ENDPOINTGROUPID |
Request Parameters
Note
Request must have content-type=application/x-www-form-urlencoded.
| Parameter Name | Description | Value |
|---|---|---|
| login | Connecting Party’s login name. | Necessity: RequiredType: StringLength: 20 |
| client_orderid | Connecting Party’s order identifier of the transaction. | Necessity: RequiredType: StringLength: 128 |
| cardrefid | Card reference ID obtained at Card Registration Stage /api/v2/create-card-ref/. | Necessity: RequiredType: StringLength: 20 |
| amount | Amount to be charged. The amount has to be specified in the highest units with . delimiter. For instance, 10.5 for USD means 10 US Dollars and 50 Cents. | Necessity: RequiredType: NumericLength: 10 |
| currency | Currency the transaction is charged in (three-letter currency code). Example of valid parameter values are: USD for US Dollar EUR for European Euro. | Necessity: RequiredType: StringLength: 3 |
| enumerate_amounts | This parameter may comprise multiple amounts, separated with ,. Billblend will cycle through the amounts of the list, try to make a payment on that amount, until there are no more amounts from the list, or not get approved. | Necessity: OptionalType: StringLength: 128 |
| recurrent_scenario | Type of the rebill transaction. Possible values: REGULAR or IRREGULAR. If this parameter is sent in the request, it will have priority over the same parameter specified on gate level. Only used for specific acquirers. | Necessity: OptionalType: StringLength: 50 |
| recurrent_initiator | Initiator of the rebill transaction. Possible values: CARDHOLDER or MERCHANT. If this parameter is sent in the request, it will have priority over the same parameter specified on gate level. Only used for specific acquirers. | Necessity: OptionalType: StringLength: 50 |
| cvv2 | Customer’s CVV2 code. CVV2 (Card Verification Value) is a three- or four-digit number AFTER the credit card number in the signature area of the card. May be empty or absent if bank gateway supports processing without CVV2. | Necessity: OptionalType: NumericLength: 3-4 |
| ipaddress | Customer’s IP address, included for fraud screening purposes. | Necessity: RequiredType: StringLength: 45 |
| comment | A short comment. | Necessity: OptionalType: StringLength: 50 |
| order_desc | Order description. | Necessity: RequiredType: StringLength: 64k |
| control | Checksum generated by SHA-1. Control string is represented as concatenation of the following parameters:1. Request parameter: login2. Request parameter: client_orderid3. Request parameter: cardrefid4. Request parameter: amount in minor units (if sent).5. request parameter: currency6. merchant_control (Control key assigned to Connecting Party account in the Billblend gateway system). | Necessity: RequiredType: StringLength: 40 |
| purpose | Destination to where the payment goes. It is useful for the Connecting Party who let their clients to transfer money from a credit card to some type of client’s account, e.g. game or mobile phone account. Sample values are: +7123456789; gamer0001@ereality.com etc. This value will be used by fraud monitoring system. | Necessity: OptionalType: StringLength: 128 |
| redirect_url | URL the cardholder will be redirected to upon completion of the transaction. Please note that the cardholder will be redirected in any case, no matter whether the transaction is approved or declined. This parameter should not be used to retrieve results from Billblend gateway, because all parameters go through client’s browser and can be lost during transmission. To deliver the correct payment result to the backend server_callback_url must be used instead. Parameter is required for 3DS flow and optional for non-3DS. https://doc.billblend.com/ can be used for testing purposes if it’s unknown whether 3DS is used or not. Use either redirect_url or combination of redirect_success_url and redirect_fail_url, not both. | Necessity: OptionalType: StringLength: 1024 |
| redirect_success_url | URL the cardholder will be redirected to upon completion of the transaction. Please note that the cardholder will be redirected only in case if the transaction is approved. This parameter should not be used to retrieve results from Billblend gateway, because all parameters go through client’s browser and can be lost during transmission. To deliver the correct payment result to the backend server_callback_url must be used instead. Parameter is required for 3DS flow and optional for non-3DS. https://doc.billblend.com/ can be used for testing purposes if it’s unknown whether 3DS is used or not. Use either redirect_url or combination of redirect_success_url and redirect_fail_url, not both. | Necessity: OptionalType: StringLength: 1024 |
| redirect_fail_url | URL the cardholder will be redirected to upon completion of the transaction. Please note that the cardholder will be redirected only in case if the transaction is declined or filtered. This parameter should not be used to retrieve results from Billblend gateway, because all parameters go through client’s browser and can be lost during transmission. To deliver the correct payment result to the backend server_callback_url must be used instead. Parameter is required for 3DS flow and optional for non-3DS. https://doc.billblend.com/ can be used for testing purposes if it’s unknown whether 3DS is used or not. Use either redirect_url or combination of redirect_success_url and redirect_fail_url, not both. | Necessity: OptionalType: StringLength: 1024 |
| server_callback_url | URL the transaction result will be sent to. Connecting Party may use this URL for custom processing of the transaction completion, e.g. to collect sales data in Connecting Party’s database. See more details at Connecting Party Callbacks. | Necessity: OptionalType: StringLength: 1024 |
| merchant_data | Any additional information for this transaction which may be useful in Connecting Party’s external systems, e.g. VIP customer, TV promo campaign lead. Will be returned in Status response and Connecting Party Callback. | Necessity: OptionalType: StringLength: 64 |
Response Parameters
Note
Response has Content-Type: text/html;charset=utf-8 header. All fields are x-www-form-urlencoded, with (0xA) character at the end of each parameter’s value.
| Sale Response Parameters | Description |
|---|---|
| type | The type of response. May be async-response, validation-error, error etc.If type equals validation-error or error, error-message and error-code parameters contain error details. |
| serial-number | Unique number assigned by Billblend server to particular request from the Connecting Party. |
| merchant-order-id | Connecting Party’s order id. |
| paynet-order-id | Order id assigned to the order by Billblend. |
| end-point-id | ID of the used End Point. |
| error-message | If status is error this parameter contains the reason for decline or error details. |
| error-code | The error code is case of error status. |
Request Example
POST /checkout/api/v2/make-rebill-preauth/46750 HTTP/1.1 Host: https://sandbox.billblend.com User-Agent: curl/7.85.0 Accept: */ Content-Length: 229 Content-Type: application/x-www-form-urlencoded Connection: close &login=login &client_orderid=902B4FF5 &cardrefid=1461665 &amount=5.00 ¤cy=USD &cvv2=321 &ipaddress=34.129.65.12 &comment=Information abount Rebill &order_desc=Rebill order description &control=a37f4972233b4a5dbfb4dcaae149ce7feed01ef9
Success Response Example
HTTP/1.1 200 Server: server Date: Thu, 02 Feb 2023 13:10:44 GMT Content-Type: text/html;charset=utf-8 Connection: close Vary: Accept-Encoding X-XSS-Protection: 1 X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000 Content-Language: en-US Strict-Transport-Security: max-age=31536000 Content-Length: 144 &type=async-response &serial-number=00000000-0000-0000-0000-000002e0d498 &merchant-order-id=902B4FF5 &paynet-order-id=6937030 &end-point-id=46750
Fail Response Example
HTTP/1.1 200 Server: server Date: Thu, 02 Feb 2023 13:18:50 GMT Content-Type: text/html;charset=utf-8 Connection: close Vary: Accept-Encoding X-XSS-Protection: 1 X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000 Content-Language: en-US Strict-Transport-Security: max-age=31536000 Content-Length: 164 type=validation-error &serial-number=00000000-0000-0000-0000-000002e0d614 &merchant-order-id=902B4FF5 &error-message=End+point+with+id+99999+not+found &error-code=3
Postman Collection
Postman Collection is available at this link – https://doc.billblend.com/integration/API_commands/api_v2_make-rebill-preauth.html#postman-collection
Request Builder
Request Builder is available at this link – https://doc.billblend.com/integration/API_commands/api_v2_make-rebill-preauth.html#request-builder
| endpointid or groupid | input ENDPOINTID or ENDPOINTGROUPID |
|---|---|
| login | |
| client_orderid | make it or use internal invoice ID |
| cardrefid | |
| amount | |
| currency | |
| enumerate_amounts | |
| recurrent_scenario | |
| recurrent_initiator | |
| cvv2 | |
| ipaddress | |
| comment | |
| order_desc | |
| merchant_control | input Control Key |
curl --data "login=login&client_orderid=902B4FF5&cardrefid=50703&amount=5.00¤cy=EUR&cvv2=321&ipaddress=34.129.65.12&comment=Information about Rebill&order_desc=Rebill order description&control=aafdcbb37b79565517b71e61c4951902dfffc208" https://sandbox.billblend.com/checkout/api/v2/make-rebill-preauth/1<?php
/**
* Executes request
*
* @param string $url Url for payment method
* @param array $requestFields Request data fields
*
* @return array Host response fields
*
* @throws RuntimeException Error while executing request
*/
function sendRequest($url, array $requestFields)
{
$curl = curl_init($url);
curl_setopt_array($curl, array
(
CURLOPT_HEADER => 0,
CURLOPT_USERAGENT => 'Billblend-Client/1.0',
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_POST => 1,
CURLOPT_RETURNTRANSFER => 1
));
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($requestFields));
$response = curl_exec($curl);
if(curl_errno($curl))
{
$error_message = 'Error occurred: ' . curl_error($curl);
$error_code = curl_errno($curl);
}
elseif(curl_getinfo($curl, CURLINFO_HTTP_CODE) != 200)
{
$error_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$error_message = "Error occurred. HTTP code: '{$error_code}'";
}
curl_close($curl);
if (!empty($error_message))
{
throw new RuntimeException($error_message, $error_code);
}
if(empty($response))
{
throw new RuntimeException('Host response is empty');
}
$responseFields = array();
parse_str($response, $responseFields);
return $responseFields;
}
function signString($s, $merchantControl)
{
return sha1($s . $merchantControl);
}
/**
* Signs payment (sale/auth/transfer) request
*
* @param array $requestFields request array
* @param string $endpointOrGroupId endpoint or endpoint group ID
* @param string $merchantControl merchant control key
*/
function signPaymentRequest($requestFields, $endpointOrGroupId, $merchantControl)
{
$base = '';
$base .= $endpointOrGroupId;
$base .= $requestFields['client_orderid'];
$base .= $requestFields['amount'] * 100;
$base .= $requestFields['email'];
return signString($base, $merchantControl);
}
/**
* Signs status request
*
* @param array $requestFields request array
* @param string $login merchant login
* @param string $merchantControl merchant control key
*/
function signStatusRequest($requestFields, $login, $merchantControl)
{
$base = '';
$base .= $login;
$base .= $requestFields['client_orderid'];
$base .= $requestFields['orderid'];
return signString($base, $merchantControl);
}
function signAccountVerificationRequest($requestFields, $endpointOrGroupId, $merchantControl)
{
$base = '';
$base .= $endpointOrGroupId;
$base .= $requestFields['client_orderid'];
$base .= $requestFields['email'];
return signString($base, $merchantControl);
}
$endpointId = 1;
$merchantControl = 'B17F59B4-A7DC-41B4-8FF9-37D986B43D20';
$requestFields = array(
'login' => 'login',
'client_orderid' => '902B4FF5',
'cardrefid' => '50703',
'amount' => '5.00',
'currency' => 'EUR',
'cvv2' => '321',
'ipaddress' => '34.129.65.12',
'comment' => 'Information about Rebill',
'order_desc' => 'Rebill order description',
);
$requestFields['control'] = signPaymentRequest($requestFields, $endpointId, $merchantControl);
$responseFields = sendRequest('https://sandbox.billblend.com/checkout/api/v2/make-rebill-preauth/1', $requestFields);
print_r($responseFields);
?>require 'net/http'
require 'uri'
require 'cgi'
require 'digest/sha1'
##
# Executes request
#
# @param url [String] Url for payment method
# @param request_fields [Hash] Request data fields
#
# @return [Hash] Host response fields
def send_request(url, request_fields)
begin
uri = URI url
response = Net::HTTP.start uri.hostname, uri.port, :use_ssl => uri.scheme == 'https' do |http|
post = Net::HTTP::Post.new uri.request_uri
post.set_form_data request_fields
http.request post
end
rescue Exception => e
raise RuntimeError, "Error occurred. #{e.message}"
end
unless Net::HTTPOK === response
raise RuntimeError, "Error occurred. HTTP code: '#{response.code}'. Server message: '#{response.message}'"
end
unless response.body
raise RuntimeError, 'Host response is empty'
end
# Change hash format from {'key' => ['value']} to {'key' => 'value'} in map block
Hash[CGI.parse(response.body).map {|key, value| [key, value.first]}]
end
def sign_string(str, merchant_control)
Digest::SHA1.hexdigest(str + merchant_control)
end
def sign_payment_request(request_fields, endpoint_or_group_id, merchant_control)
base = ''
base += endpoint_or_group_id
base += request_fields['client_orderid']
base += (request_fields['amount'].to_f * 100).to_i
base += request_fields['email']
sign_string(base, merchant_control)
end
def sign_status_request(request_fields, login, merchant_control)
base = ''
base += login
base += request_fields['client_orderid']
base += request_fields['orderid'].nil? ? '' : request_fields['orderid']
sign_string(base, merchant_control)
end
request_fields = {
'login' => 'login',
'client_orderid' => '902B4FF5',
'cardrefid' => '50703',
'amount' => '5.00',
'currency' => 'EUR',
'cvv2' => '321',
'ipaddress' => '34.129.65.12',
'comment' => 'Information about Rebill',
'order_desc' => 'Rebill order description',
'control' => 'aafdcbb37b79565517b71e61c4951902dfffc208'
};
response_fields = send_request('https://sandbox.billblend.com/checkout/api/v2/make-rebill-preauth/1', request_fields);
require 'pp'
pp response_fields
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Main {
//Transactions are initiated by using URL in the following format: /checkout/api/v2/TRANSACTION_TYPE/ENDPOINTID or /checkout/api/v2/TRANSACTION_TYPE/ENDPOINTGROUPID (if group is supported)
//Use "gate" for production purposes or "sandbox" for integration needs
private static String targetURL = "https://sandbox.billblend.com/checkout/api/v2/make-rebill-preauth/1";
//Request parameters
private static String urlParameters = "login=login&client_orderid=902B4FF5&cardrefid=50703&amount=5.00¤cy=EUR&cvv2=321&ipaddress=34.129.65.12&comment=Information about Rebill&order_desc=Rebill order description&";
//String for calculating control code parameter
private static String controlParameters = "login902B4FF550703500EURB17F59B4-A7DC-41B4-8FF9-37D986B43D20";
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
//Sending POST request to the specified URL with request parameters and SHA1-encrypted control parameter
System.out.println(executePost(targetURL, urlParameters + "control= " + sha1(controlParameters)));
}
static String sha1(String input) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input.getBytes("utf-8"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
public static String executePost(String targetURL, String urlParameters)
{
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\n');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
}