3.17. /api/v2/void

Introduction

VoidΒ can only be processed forΒ SaleΒ andΒ CaptureΒ transactions in the final successful status (SeeΒ Statuses). To make a void request send anΒ HTTPS POSTΒ request to theΒ URLsΒ and theΒ parameters. UseΒ SHA-1Β for authentication.

API URLs

IntegrationProduction
https://sandbox.billblend.com/checkout/api/v2/void/ENDPOINTIDhttps://pay.billblend.com/checkout/api/v2/void/ENDPOINTID
https://sandbox.billblend.com/checkout/api/v2/void/group/ENDPOINTGROUPIDhttps://pay.billblend.com/checkout/api/v2/void/void/ENDPOINTGROUPID

Request Parameters

Note

Request must have content-type=application/x-www-form-urlencoded.

Warning

The following characters must be escaped in the parameter values: & + β€œ.

Parameter NameDescriptionValue
loginConnecting Party login name.Necessity: MandatoryType: StringLength: 20
orderidUnique order identifier assigned by Billblend system.Necessity: MandatoryType: StringLength: 20
client_orderidUnique Connecting Party identifier.Necessity: MandatoryType: NumericLength: 10
amountThis optional parameter specifies amount to be reversed.Necessity: MandatoryType: StringLength: 10
currencyCurrency the transaction is charged in (See:Β Currency codes). Sample values are:Β USDΒ for US DollarΒ EURΒ for European Euro.Necessity: ConditionalType: StringLength: 3
controlChecksum generated byΒ SHA-1. Control string is represented as concatenation of the following parameters:1. Request parameter:Β login2. Request parameter:Β client_orderid3. Request parameter:Β orderid4.Β merchant_controlΒ (Control key assigned to Connecting Party account in the Billblend gateway system).Necessity: ConditionalType: StringLength: 128
commentA brief description of reason.Necessity: MandatoryType: StringLength: 50

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.

Parameter NameDescription
typeThe type of response. May be async-response, validation-error, error. If type equals validation-error or error, error-message and error-code parameters contain error details
paynet-order-idOrder id assigned to the order by Billblend.
merchant-order-idConnecting Party order id.
serial-numberUnique number assigned by Billblend server to particular request from the Connecting Party.
end-point-idEntry point used for processing this transaction.
error-messageIf status is error this parameter contains the reason for decline or error details.
error-codeThe error code is case of error status.

Request Example

POST /checkout/api/v2/void/39914 HTTP/1.1
Host: sandbox.billblend.com
User-Agent: curl/7.83.0
Accept: */*
Content-Length: 123
Content-Type: application/x-www-form-urlencoded
Connection: close

login=Test
&client_orderid=55
&orderid=6862995
&comment=Service not provided
&control=246e0a2074f9e4b84cff59b2567ed48ec3aab87d

Success Response Example

HTTP/1.1 200 OK
Server: server
Date: Tue, 16 Aug 2022 06:57:40 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: 138

type=async-response
&serial-number=00000000-0000-0000-0000-000002ddae76
&merchant-order-id=55
&paynet-order-id=6862995
&end-point-id=39914

Fail Response Example

HTTP/1.1 200 OK
Server: server
Date: Tue, 16 Aug 2022 07:21:37 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: 148

type=validation-error
&serial-number=00000000-0000-0000-0000-000002ddae78
&merchant-order-id=Test
&error-message=INVALID_CONTROL_CODE
&error-code=2

Postman Collection

Postman Collection is available at this link – https://doc.billblend.com/integration/API_commands/api_v2_void.html#postman-collection

Request Builder

Request Builder is available at this link – https://doc.billblend.com/integration/API_commands/api_v2_void.html#request-builder

Endpointid or groupidinput ENDPOINTID or ENDPOINTGROUPID
login
client_orderidinput Invoice Number
orderid
amount
currency
merchant_controlinput Control Key
comment
curl --data "login=logic&client_orderid=902B4FF5&orderid=159884&amount=10.42&currency=EUR&comment=Service not provided&control=7f5e4878d1cc6788c0dc613930e663f93e54f763" https://sandbox.billblend.com/checkout/api/v2/void/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' => 'logic', 
    'client_orderid' => '902B4FF5', 
    'orderid' => '159884', 
    'amount' => '10.42', 
    'currency' => 'EUR', 
    'comment' => 'Service not provided', 

);

$requestFields['control'] = signPaymentRequest($requestFields, $endpointId, $merchantControl);

$responseFields = sendRequest('https://sandbox.billblend.com/checkout/api/v2/void/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' => 'logic', 
    'client_orderid' => '902B4FF5', 
    'orderid' => '159884', 
    'amount' => '10.42', 
    'currency' => 'EUR', 
    'comment' => 'Service not provided', 

    'control' => '7f5e4878d1cc6788c0dc613930e663f93e54f763'
};

response_fields = send_request('https://sandbox.billblend.com/checkout/api/v2/void/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/void/1";
    //Request parameters
    private static String urlParameters = "login=logic&client_orderid=902B4FF5&orderid=159884&amount=10.42&currency=EUR&comment=Service not provided&";
    //String for calculating control code parameter
    private static String controlParameters = "1logic902B4FF51598841042EURB17F59B4-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();
            }
        }
    }
}

Contact us

Contact us in Telegram

By clicking on the button, you agree to theΒ data protectionΒ policy

Complete the quiz

By clicking on the button, you agree to theΒ data protectionΒ policy