Documentation - Developers Center
 
 

eCommerce Introduction

Payfirma’s payment solutions allow you to securely and safely accept payments for your website or online store; whether your customers are purchasing on their mobile device or from the comfort of home on their desktop.

We handle the complexities of PCI Compliance for your site, while maintaining complete reliability and safety throughout the entire integration process.

Use our API to easily take payments, create a seamless user-experience on your own platform, and ensure all data is secure for peace of mind.

Accessing The Payfirma JavaScript Library

Including the Payfirma JavaScript code in your payment form allows you to encrypt credit card information well before it is transmitted across the Internet. This encrypted information is passed to your server where you can make a simple server-to-server call to process the transaction. Information on both Client-Side & Server-Side calls are included in our library.

To access our JavaScript Library, use the following URL: http://www.payfirma.com/media/payfirma.minified.js

Have some questions? Get in touch with us: 
developers@payfirma.com

Toggle between PHP and JAVA languages at any time in our documentation to display code examples alongside their respective documentation.

Check back soon for even more language support!

Find us on github - https://github.com/Payfirma 
Toggle between PHP and JAVA languages at any time in our documentation to display code examples alongside their respective documentation.

Check back soon for even more language support!

Find us on github - https://github.com/Payfirma 
 

API Access

Working with the API requires two credentials from your eCommerce settings in PayHQ; your Merchant ID and API Key. You will also need your Public Encryption Key for use with the JavaScript library. All of these can be found within the eCommerce settings of your PayHQ page. In order to access these settings, you’ll need developer access to PayHQ.

To sign up as a developer click here.

Step 1:

      From the PayHQ homepage, click on the Settings icon.
   Settings

Step 2:

      On the left side of the screen beneath the PayHQ icon, you will find your Settings categories; Receipt Settings and eCommerce Settings. Click on eCommerce to access your Merchant ID, API Key, and Public Encryption Key, as well as the ability to reset and refresh the keys. 
ecommsettings
    • Here you have access to your Merchant ID, API Key, and Public Encryption Key, as well as the ability to reset and refresh the keys. You can also set the URL for your Push API here.
ecommID
Note:
    When you refresh your API or Encryption Key, you must be prepared to make the relevant changes in your own code. Once a refresh takes place, it CANNOT be undone, and will not allow your eCommerce store to accept payments until you make the necessary changes.
 
  
 

Security

We require an SSL Certificate for use with all of our eCommerce API. Secure Socket Layer, or SSL, allows you to protect customer data as it is being transmitted to and from the web server. SSL Certificates can be purchased through a variety of places, including your service provider or host, and other hosting domains and locations.

All server-side communication must be conducted using the HTTPS protocol, enabled by an SSL Certifcate, so that Payfirma and PayHQ can handle PCI Compliance.
 
  
 

Client-Side Introduction

On the Client side, to successfully create a ‘Payfirma’ object, you will require the following:
Payfirma(PublicKey, { CARD DATA }, {META-DATA}, ‘URL’, CALLBACK_FUNCTION);

PublicKey: Your public encryption key as supplied to you in your eCommerce settings. Refreshing your encryption key will impact all transactions if not updated in your codebase immediately.

PublicEncryption
Card Data:
The credit card data to be encrypted. This is required for Sales and Authorizations. Although optional for Captures and Refunds, we recommend against using it for both. This is to reduce risk of fraud, as Capture and Refund transactions only call on previously sent data.

Meta Data: This is what is required for all of the additional data you may want or need to have associated with a transaction for your business. This includes transaction amounts, customer records, and transaction descriptions. Examples of additional fields are included in the library.

URL: Your chosen Server-side URL where the transaction data will be posted.

Example: https://your-server.com/script.php

CALLBACK: The JavaScript function that will handle displaying the Server response to your customer.

 
  
 

Processing Transaction Requirements

In order to process a standard transaction, a number of fields are necessary; in the sections below, you’ll find these required fields with optional information for making payments. Coding examples are of course included alongside this information.

Below, you’ll find all transaction possibilities from Sales to Refunds, as well as their parameters in the code window.
 
  
 

Sale

These are the required parameters for completing a Sale using the Payfirma object.

Parameter Name Description
PublicKey Your Payfirma provided Public Encryption Key.
card_number Customer credit card number (16 digits for most card brands, 15 digits for American Express).
card_expiry_month The double digit month the card expires
card_expiry_year The double digit year the card expires. Ex. 11/16 as an expiry date, making the expiration November 2016.
amount The amount of the transaction

Optional

“cvv2″: A credit card’s verification code, otherwise known as CVC or CVV; the three or four digit number on the back of most major cards, and the four digit number found on the front of American Express cards. We strongly recommend that you utilize the cvv2 field to help protect against fraud and charge-backs.
//Client-Side JavaScript in HTML file or similar
function callback(response) {
		console.log(response);
	};
	document.querySelector('button').onclick = function(e) {

	var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/server-side.jsp', callback);
	}; 
//Client-Side JavaScript in HTML file or similar

function callback(response) {
		console.log(response);
	};
	document.querySelector('button').onclick = function(e) {

	var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/server-side.php', callback);
	}; 
 

Authorization

These are the required parameters for completing an Authorization using the Payfirma object.
Parameter Name Description
PublicKey Your Payfirma provided Public Encryption Key.
card_number Customer credit card number (16 digits for most card brands, 15 digits for American Express).
card_expiry_month The double digit month the card expires
card_expiry_year The double digit year the card expires. Ex. 11/16 as an expiry date, making the expiration November 2016.
amount The amount of the transaction

Optional

“cvv2″: A credit card’s verification code, otherwise known as CVC or CVV; the three or four digit number on the back of most major cards, and the four digit number found on the front of American Express cards. We strongly recommend that you utilize the cvv2 field to help protect against fraud and charge-backs.
//Client-Side JavaScript in HTML file or similar
function callback(response) {
		console.log(response);
	};

	document.querySelector('button').onclick = function(e) {

		var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/auth_server-side.jsp', callback);

	}; 
//Client-Side JavaScript in HTML file or similar
function callback(response) {
		console.log(response);
	};

	document.querySelector('button').onclick = function(e) {

		var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/auth_server-side.php', callback);

	}; 
 

Capture

These are the required parameters for completing a Capture using the Payfirma object.
Parameter Name Description
original_id Transaction ID of the Authorization to be captured. This reference number is required to properly complete Capture transactions.
amount The amount of the transaction.

NOTE:
This data can be combined to include additional sales meta data before passing to your web server.
//Client-Side JavaScript in HTML file or similar
function callback(response) {
		console.log(response);
	};

	document.querySelector('button').onclick = function(e) {

		var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/capture.jsp', callback);

	}; 
//Client-Side JavaScript in HTML file or similar
function callback(response) {
		console.log(response);
	};

	document.querySelector('button').onclick = function(e) {

		var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/capture.php', callback);

	}; 
 

Refund

These are the required parameters for completing a Refund using the Payfirma object.
Parameter Name Description
original_id Transaction ID of the Sale or Capture to be refunded. This reference number is required to properly complete Refund transactions.
amount The amount of the transaction.

NOTE:
This data can be combined to include additional sales meta data before passing to your web server.
 
//Client-Side JavaScript in HTML file or similar
function callback(response) {
		console.log(response);
	};

	document.querySelector('button').onclick = function(e) {

		var doc = document;

		var card_number = doc.querySelector('input[name="card_number"]').value;
		var card_expiry_month = doc.querySelector('input[name="card_expiry_month"]').value;
		var card_expiry_year = doc.querySelector('input[name="card_expiry_year"]').value;
		var cvv2 = doc.querySelector('input[name="cvv2"]').value;

		var first_name = doc.querySelector('input[name="first_name"]').value;
		var last_name = doc.querySelector('input[name="last_name"]').value;

		var key = 'PUBLIC_API_KEY_HERE';
		var z = new Payfirma(key, {
			'card_number': card_number,
			'card_expiry_month': card_expiry_month,
			'card_expiry_year':  card_expiry_year,
			'cvv2': cvv2
		}, {
			'first_name': first_name,
			'last_name': last_name
		}, 'https://www.YOUWEBSITEADDRESS.com/refund.php', callback);

	}; 
 

Meta Data Examples

Meta data allows you to add any additional details you may want or need to have associated with a transaction for your business. This includes transaction amounts, customer records, and transaction descriptions.

Examples of PayHQ meta data are included in the code window, however you can always add additional fields of your choosing within the server-side module. This information will however not be stored in PayHQ, and is up to you to record and maintain.
//
Element Name Description
“email” Customer’s email address. Email addresses are used to link the transaction to the customer. If the customer’s email does not exist within My Customers during lookup, a new customer is created. By default PayHQ will send a receipt to the customer’s provided email address.
“first_name” The customer’s first name.
“last_name” The customer’s last name.
“address1″ Customer’s primary address line.
“address2″ Secondary address line.
“city” Customer’s city.
“province” Customer’s province.
“country” Customer’s country.
“postal_code” Customer’s postal code.
“company” Customer’s company or business name.
“telephone” Customer’s phone number.
“description” Description of transaction.
“order_id” Order identifier.
“invoice_id” Invoice identifier.
“amount_tax” Used to indicate the dollar amount of any taxes applied to transactions.
“amount_tip” Used to indicate the dollar amount of any tips applied to transactions.
“currency” When using more than one Gateway, it is possible to alternate between CAD and USD using the values "CA$" and "US$"
“bcc_emails” Used to send blind carbon email copies. Will only work if a primary email is selected
//
Element Name Description
“email” Customer’s email address. Email addresses are used to link the transaction to the customer. If the customer’s email does not exist within My Customers during lookup, a new customer is created. By default PayHQ will send a receipt to the customer’s provided email address.
“first_name” The customer’s first name.
“last_name” The customer’s last name.
“address1″ Customer’s primary address line.
“address2″ Secondary address line.
“city” Customer’s city.
“province” Customer’s province.
“country” Customer’s country.
“postal_code” Customer’s postal code.
“company” Customer’s company or business name.
“telephone” Customer’s phone number.
“description” Description of transaction.
“order_id” Order identifier.
“invoice_id” Invoice identifier.
“amount_tax” Used to indicate the dollar amount of any taxes applied to transactions.
“amount_tip” Used to indicate the dollar amount of any tips applied to transactions.
“currency” When using more than one Gateway, it is possible to alternate between CAD and USD using the values "CA$" and "US$"
“bcc_emails” Used to send blind carbon email copies. Will only work if a primary email is selected
 

Test Transactions

After you’ve applied the parameters to your URL, you can test out your code by processing a test transaction.  Simply apply the additional parameter, “test_mode”.

By setting this value to true, your transactions will not require many of the checks that are made for valid credit cards. The entire test process is simulated from entering the transaction cost, to the approval or decline of the card.For your tests, we recommend using the following test card info: PAYFIRMA VISA
A card’s Security Code, otherwise known as CVC or CVV,  is the three or four digit number on the back of most major cards, and located on the front of American Express cards. You can test both the integration and your transactions while viewing the results in real time using “My Transactions” within PayHQ.
 
  
 

Sale Test

In order for a transaction be flagged as a test, the following URL can be passed to initiate the sale:
https://ecom.payfirma.com/sale/?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&test_mode=true
Note: When testing transactions, any amount that is a whole, odd dollar amount will result in an Approved transaction: $51.20, $229.83. Any amount that is a whole, even dollar amount will result in a Declined transactions: $40.11, $102.34. Whatever amount following the decimal point (cents) do not affect test transactions.
	public static void main(String[] args)
	{
		URL url = null;
        URLConnection connection = null;
        String inputLine = "";

        try
        {
            url = new URL("https://ecom.payfirma.com/sale/?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&amount=0.02");
            connection = url.openConnection();
            connection.setDoOutput(true);
            
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
            out.write("card_number=4111111111111111&card_expiry_month=12&card_expiry_year=34&cvv2=123");
            out.close();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null)
            {
                System.out.println(inputLine);
            }
            inStream.close();
        }
        catch (MalformedURLException me)
        {
            System.err.println("MalformedURLException: " + me);
        }
        catch (IOException ioe)
        {
            System.err.println("IOException: " + ioe);
            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try
            {
                int data = error.read();
                while (data != -1) {
                    //System.out.println(data);
                    inputLine = inputLine + (char)data;
                    data = error.read();
                    //inputLine = inputLine + (char)data;
                }
                error.close();
            }
            catch (Exception ex)
            {
                try
                {
                    if (error != null)
                    {
                        error.close();
                    }
                }
                catch (Exception e)
                {
                }
            }
        }
        System.out.println(inputLine);
	} 

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ecom.payfirma.com/sale');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);

$data = array(
	'merchant_id'=>'YOUR_MERCHANTID',
	'key'=>'YOUR_PAYFIRMA_API_KEY',
	'amount'=>'20.00',
	'token'=>$_REQUEST['token'],
	'first_name'=>$_REQUEST['first_name'],
	'last_name'=>$_REQUEST['last_name']
	);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);

echo $output; 
 

Authorization Test

An Authorize test allows you to see if a card is capable of completing a payment without collecting the funds. Typical Authorizations will secure funds for five business days, and can be collected at any point during.
https://ecom.payfirma.com/authorize/?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&test_mode=true
	public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/authorize/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&amount=0.02&method=POST");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ecom.payfirma.com/authorize');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);

$data = array(
	'merchant_id'=>'YOUR_MERCHANTID',
	'key'=>'YOUR_PAYFIRMA_API_KEY',
	'amount'=>'20.00',
	'token'=>$_REQUEST['token'],
	'first_name'=>$_REQUEST['first_name'],
	'last_name'=>$_REQUEST['last_name']
	);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);

echo $output; 
 

Capture Test

Capture is the process that completes previous Authorizations, and allows transaction funds to be collected from customers. As long as it is within five business days of the original transaction, all funds will be collected, though you can collect more than the original Authorization, if needed.
https://ecom.payfirma.com/capture/?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&test_mode=true
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/capture/YOUR_AUTH_TRANSACTION_ID?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&amount=0.02&method=POST");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 


$url = 'https://ecom.payfirma.com/capture/{{ transaction id from authorization }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'amount' => '12.00' // amount being captured, must be less than or equal to authorized amount
);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Refund Test

Refunds are a way to return funds to your customer after Sale or Capture transactions have taken place.  We currently do not set limits on the time between sale and refund, as many businesses have varying return or exchange policies.
	public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/refund/ORIGINAL_TRANSACTION_ID?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&amount=0.02&method=POST");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.err.println("IOException: " + ioe);
            InputStream error = ((HttpURLConnection) connection).getErrorStream();
            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/refund/{{ transaction id being refunded }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'amount' => '12.00' // amount being refunded, must be less than or equal to original transaction
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Retrieval Test

A retrieval is the fastest way for calling on transaction information stored through previous sales, authorizations, captures and refunds. Using the GET method, the required data is returned. 

A retrieval can be beneficial for merchants requiring information on previous sales.
Parameter Name Description
original_id This is the original transaction ID which can be called back.
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/transaction/ORIGINAL_TRANSACTION_ID?merchant_id=YOURMERCHANTID&key=YOURAPIKEY");
            connection = url.openConnection();

            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/transaction/{{ transaction id }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'method' => 'GET'
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Customer Vault

The Customer Vault is best described as a way to securely store your customer’s information.  From contact, to payment information, you can use Customer Vault as a means of staying in touch with your customers, or speed up their transaction process.

Using the Customer Vault API, you can store and handle your customers’ details within PayHQ.  Below, you’ll find the sample URL requests used to complete all available actions within Customer Vault. Feel free to pass through either HTTP request method, or by specifying a “method” variable.

Whenever you save a customer’s credit card, Vault will require the following:
  • Customer’s email address
  • Customer’s first name
  • Customer’s last name
  • Customer’s credit card information
All information stored within Customer Vault is kept under lock and key with the highest safety and security standards.
 
  
 

Creating A New Customer Record

Creating a new customer record, with or without credit card details, primarily involves the use of the following URL:
https://ecom.payfirma.com/vault/customer@domain.com?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&method=POST
See our breakdown of the URL below.

All additional parameters that MUST be sent as POST variables. 
card_number=4111111111111111&card_expiry_month=12&card_expiry_year=34&cvv2=123&first_name=Ron&last_name=Swanson
The URL breakdown is as follows: first)name=’Ron’First Namelast_name=’Swanson’Last Name
https://ecom.payfirma.com/vault/ The target URL
customer@domain.com Either the customer’s saved email or lookup ID
key=### The API key provided, as found in eCommerce Settings
merchant_id=### Your assigned Merchant ID, as found in eCommerce Settings
card_number=4111111111111111 Customer’s card number
card_expiry_month=12 Card expiry month
card_expiry_year=13 Card expiry year
cvv2=121 Card verification value
first_name=’Ron’ Card verification value
last_name=’Swanson’ Card verification value
[method=POST] [Optional] Used to override the HTTP method, this particular API function requires the use of POST for the method

What is returned:

{“first_name”:”###”,”last_name”:”###”,”email”:”###”,”cards”:”###”,”lookupid”:###}
Note: “cards” index includes:
[{"card_lookup_id":0,"default":true,"card_expiry":"01/20","card_suffix":"1111","card_description":"Card1"}, 
{"card_lookup_id":1,"default":false,"card_expiry":"01/21","card_suffix":"2222","card_description":"Card2"}]


Note: The transaction will fail to authorize if the card is not valid
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/vault/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY");
            connection = url.openConnection();
            connection.setDoOutput(true);
            
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
            out.write("card_number=4111111111111111&card_expiry_month=12&card_expiry_year=13&cvv2=121&first_name=Ron&last_name=Swanson");
            out.close();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

// Receive POST'ed data
$token = $_REQUEST['token'];


$url = 'https://ecom.payfirma.com/vault/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'token' => $token, // contains card info
	'first_name' => 'Ron',
	'last_name' => 'Swanson'
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Retrieving A Customer’s Details

If a customer is making multiple purchases, or you are using their contact information as a security check, you can quickly retrieve the information through the following URL:
https://ecom.payfirma.com/vault/customer@domain.com?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&method=GET
The URL breakdown is as follows: 
https://ecom.payfirma.com/vault/ The target URL
customer@domain.com Either the customer’s saved email or lookup ID
key=### The API key provided, as found in eCommerce Settings
merchant_id=### Your assigned Merchant ID, as found in eCommerce Settings
[method=GET] [Optional] Used to override the HTTP method, this particular API function requires the use of GET for the method

What is returned:

{“first_name”:”###”,”last_name”:”###”,”email”:”###”,”cards”:”###”,”lookupid”:###}
Note: “cards” index includes:
[{"card_lookup_id":0,"default":true,"card_expiry":"01/20","card_suffix":"1111","card_description":"Card1"}, 
{"card_lookup_id":1,"default":false,"card_expiry":"01/21","card_suffix":"2222","card_description":"Card2"}]
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/vault/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/vault/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'method' => 'GET' // override POST method
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Adding a New Customer’s Card

Creating a new customer record, with or without credit card details, primarily involves the use of the following URL:
https://ecom.payfirma.com/vault/customer@domain.com?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&method=POST
See our breakdown of the URL below.

All additional parameters that MUST be sent as POST variables. 
card_number=4111111111111111&card_expiry_month=12&card_expiry_year=34&cvv2=123
The URL breakdown is as follows:
https://ecom.payfirma.com/vault/The target URL
customer@domain.comEither the customer’s saved email or lookup ID
key=###The API key provided, as found in eCommerce Settings
merchant_id=###Your assigned Merchant ID, as found in eCommerce Settings
card_number=4111111111111111Customer’s card number
card_expiry_month=12Card expiry month
card_expiry_year=13Card expiry year
cvv2=121Card verification value
[method=POST][Optional] Used to override the HTTP method, this particular API function requires the use of POST for the method

What is returned:

{“first_name”:”###”,”last_name”:”###”,”email”:”###”,”cards”:”###”,”lookupid”:###}

Note: “cards” index includes:
[{"card_lookup_id":0,"default":true,"card_expiry":"01/20","card_suffix":"1111","card_description":"Card1"}, 
{"card_lookup_id":1,"default":false,"card_expiry":"01/21","card_suffix":"2222","card_description":"Card2"}]
 
  
 

Removing A Customer’s Card Details

Not all customers are return customers, so if someone asks to have their payment information removed from your Vault, you can make use of this URL:
https://ecom.payfirma.com/vault/customer@domain.com?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&card_lookup_id=YOURCARDLOOKUPID&method=DELETE
The URL breakdown is as follows:
https://ecom.payfirma.com/vault/ The target URL
customer@domain.com Either the customer’s saved email or lookup ID
key=### The API key provided, as found in eCommerce Settings
merchant_id=### Your assigned Merchant ID, as found in eCommerce Settings
card_lookup_id=### The ID number associated with the card
[method=DELETE] [Optional] Used to override the HTTP method, this particular API function requires the use of DELETE for the method

If a card lookup id is not specified, the default card will be removed. The oldest card in the system will become the new default.

All recurring subscriptions associated with a card must be cancelled or updated before a card can be removed

What is returned:

 {"result":"Success","message":"Customer payment data deleted"}
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/vault/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&method=DELETE");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/vault/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'card_lookup_id' => '{{ your card lookup id }}',
	'method' => 'DELETE' // override POST method
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Customer Vault Test

The Customer Vault allows you to store and handle your customers’ information, and even payment details within PayHQ. You’ll want to test out this process before you begin storing your customer’s credit cards.
 
  
 

Performing Sales With A Vault Customer

Once a saved customer profile is located within the Vault, it is possible to perform a sale with their saved details.You can find the Vault Sale code located in the Code Frame.

In order to charge to a card other than the default card stored, add the parameter “card_lookup_id=####” to the array.
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/sale/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&amount=0.02&method=POST");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/sale/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'amount' => '14.00'
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Authorization For A Vault Customer

After a customer is located within the Vault, you can perform an authorization using their details. The code you’ll need to perform this transaction can be found in the Code Frame.

In order to charge to a card other than the default card stored, add the parameter “card_lookup_id=####” to the array.
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/authorize/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&amount=0.02&method=POST");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/authorize/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'amount' => '14.00'
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Customer Vault Notes

Expiring Cards

As a card approaches it’s expiration date, it triggers a variety of notifications to the merchant through both email and PayHQ.Even though a customer’s card is saved to Vault and being charged, it can expire.

If a card fully expires, all future payments will be declined.  Every credit card expires on the final day of its expiry date, so we email out expiration warning first at 90 days, and then 30 days before expiration.  These notifications are to provide you enough time to contact your customer, or for them to renew their card and get back to you with updated card details.
 
  
 

Recurring Billing

It’s easiest to remember Recurring Billing as automated payments.  Although Recurring can only be used with stored credit cards; subscribing a customer to a Recurring Plan means that they can be billed on a specific date, at a specific frequency or one-off payment, for whatever amount you choose.

Before you begin using the Recurring Billing API, ensure that you have been able to properly integrate with our Customer Vault API. Customer information is required for automated payments and scheduled bills. As with Customer Vault API, you’ll find the sample URL below, for requesting your action.
 
  
 

Subscribing To A Plan

After you’ve created a plan in PayHQ, you’ll be able to sign up any of your customers to the plan through the following URL:
https://ecom.payfirma.com/recurring/customer@domain.com?key=YOURAPIKEY&merchant_id=YOURMERCHANTID& plan_name=PlanName&start_date=2014-10-19&amount=14.00&method=POST
The URL breakdown is as follows:
https://ecom.payfirma.com/recurring/ The target URL
customer@domain.com Either the customer’s saved email or lookup ID
key=### The API key provided, as found in eCommerce Settings
merchant_id=### Your assigned Merchant ID, as found in eCommerce Settings
plan_name=PlanName The case sensitive name of the plan created within PayHQ
start_date=2014-10-19 The date the plan commences (year/month/date)
[amount=14.00] [Optional] The amount that is billed per cycle, if omitted, the payments will defer to the default plan amount.  If included, it will override the current plan cost.
[method=POST] [Optional] Used to override the HTTP method, this particular API function requires the use of POST for the method

What is returned:

{“id”:###,”customer”:###,”amount”:40.00,”plan_name”:”###”,”start_date”:”2014-01-01″, ”frequency”:”daily”,”cycles”:123}
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

//CREATE PLAN CALLED APPLES - START DATE JAN 1
        try {
            url = new URL("https://ecom.payfirma.com/recurring/customer@email.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&plan_name=Apples&start_date=2014-01-01&method=POST");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 
 
$url = 'https://ecom.payfirma.com/recurring/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'plan_name' => '{{ recurring plan name }}',
	'start_date' => '{{ yyyy-mm-dd }}', // date of first transaction
	'amount' => '14.00', // [optional, defaults to plan setting]
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Retrieving Recurring Plan Details

To view a recurring plan’s details you can pass the following URL:
https://ecom.payfirma.com/recurring/customer@domain.com?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&method=GET

What is returned:

[{"id":1,"name":"PlanName1","frequency":"daily","description":"","amount":"0.01"},
{"id":2,"name":"PlanName2","frequency":"weekly","description":"","amount":"0.02"}]

or

{"No plans found"}
 
$url = 'https://ecom.payfirma.com/recurring/{{ customer email address }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'method' => 'GET' 
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Cancelling A Subscription

In the event that a customer no longer wishes to continue their subscription, or must be removed from one, all that is required is to know the customer’s Recurring Plan ID. Identifying the plan ID before a “method=delete” will remove the subscription from the customer.

For the example below, the customer’s recurring plan ID is 51.
https://ecom.payfirma.com/recurring/51?key=YOURAPIKEY&merchant_id=YOURMERCHANTID&method=delete
public static void main(String[] args) {
		URL url;
        URLConnection connection = null;
        String inputLine = "";

        try {
            url = new URL("https://ecom.payfirma.com/recurring/RECURRINGID?merchant_id=YOURMERCHANTID&key=YOURAPIKEY&method=DELETE");
            connection = url.openConnection();
            
            BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {

            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    inputLine = inputLine + (char)data;
                    data = error.read();
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {
                    System.out.println("Unhandled error");
                }
            }
            System.out.println(inputLine);
        }
	} 

$url = 'https://ecom.payfirma.com/recurring/{{ customer recurring plan id }}';

$post_fields = array(
	'key' => '{{ your api key }}',
	'merchant_id' => '{{ your merchant id }}',
	'method' => 'DELETE' // override POST method
	);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch); 
 

Push API

HTTP POST

Our Push API is best used for real-time delivery of all the transaction details from your account.  Each message is sent in JSON format, and uses the HTTP POST method.

Push API can store multiple forms of meta data from a completed transaction.To set your Push API URL access your eCommerce Settings in Pay HQ and enter it as shown below. 
PushAPI  
Each Push API is displayed in the eCommerce Settings of PayHQ, and will display the previous 10 Push responses.

The Push API is not available for Recurring Billing at this time.
Example of Push Data

{
 ”id”:”###”,
 ”amount”:”###”,
 ”email”:”###”,
 ”first_name”:”###”,
 ”last_name”:”###”,
 ”address1″:”###”,
 ”address2″:”###”,
 ”city”:”###”,
 ”province”:”###”,
 ”country”:”###”,
 ”postal_code”:”###”,
 ”company”:”###”,
 ”telephone”:”###”,
 ”description”:”###”,
 ”order_id”:”###”,
 ”invoice_id”:”###”,
 ”custom_id”:”###”,
 ”currency”:”###”,
 ”merchant_id”:”###”,
 ”transaction_type”:”###”,
 ”result”:”Approved”,
 ”result_bool”:true
 } 
Example of Push Data

{
 ”id”:”###”,
 ”amount”:”###”,
 ”email”:”###”,
 ”first_name”:”###”,
 ”last_name”:”###”,
 ”address1″:”###”,
 ”address2″:”###”,
 ”city”:”###”,
 ”province”:”###”,
 ”country”:”###”,
 ”postal_code”:”###”,
 ”company”:”###”,
 ”telephone”:”###”,
 ”description”:”###”,
 ”order_id”:”###”,
 ”invoice_id”:”###”,
 ”custom_id”:”###”,
 ”currency”:”###”,
 ”merchant_id”:”###”,
 ”transaction_type”:”###”,
 ”result”:”Approved”,
 ”result_bool”:true
 } 
 

iOS Integration

Using this guide will help you to integrate any iOS app with the Payfirma Mobile Application, or Mobile HQ, using a handoff (hooks) method.

We’ve included an example use case, the input/output variables, and a piece of sample code to guide you through the process.
 
  
 

iOS Use Case

For this example, we’ll use Acme. Acme is an invoicing app for businesses creating invoices for their customers. Acme invoices can be sent by email or delivered in person, however, Acme lacks the ability to for businesses to accept credit card payments using their app. By integrating with Payfirma, businesses using Acme are able to accept payments using a customer’s credit card.

iOS interaction
  1.  A salesperson creates an invoice using the Acme app with an amount and a sale or product description.
  2.  The Acme app has a “Pay Now” button that calls the Payfirma app and passes the total, description and optional login credentials.
  3.  The Payfirma app is pre-populated with the total, description and any additional data, so the user needs only enter the customer’s credit card information.
  4.  The transaction is processed within the Payfirma app and a receipt is sent out.
  5.  The Payfirma app automatically closes and reopens the Acme app, passing the transaction ID and transaction status back to the invoicing app.
 
  
 

iOS Input Variables

Input variables are used to pass values or information from your app to Mobile HQ, so that it can be pre-populated with the transaction type, amount, and a description. Values do not need to be pre-populated, but they will speed up the process. Without any amounts or information, they will need to be entered manually a second time.

During the transaction and within in the Payfirma app, the user may alter the manually entered or pre-populated variables, such as description or amount; the final values in the Payfirma app are what will be used for the transaction.

NOTE: In the event that the app being used is additionally allowing or tracking login credentials, it is paramount that security measures be taken, so that both usernames as well as passwords are kept protected from outside access or auto-fill functions. The input variables should be added to the Payfirma URL as follows:
NSString *stringURL = @"payfirmahq://process?amount=1.25&description=a%20piece%20of%20toast&transaction_type=SALE";
URL parameters cannot contain spaces. As such, you should use:
stringByAddingPercentEscapesUsingEncoding
and
stringByReplacingPercentEscapesUsingEncoding
to encode/decode your strings.
//
Variable Name Type Description
transaction_type String This selects the transaction: Sale, Authorize or Refund
amount String This inputs the amount to be transacted
description String This inputs the optional description for the transaction
orig_ID String This populates the transaction ID of previous transactions (for refunds only)
return_url String The name of the URL used to return to your app (your_app://your_return_function)
sending_app String The name of your app
auto_return String Yes/No string for whether the app should wait for user action before returning to the calling app
email String This input will populate the email field for a customer’s receipt destination
user String Your PayHQ username
password String Your PayHQ password
//
Variable Name Type Description
transaction_type String This selects the transaction: Sale, Authorize or Refund
amount String This inputs the amount to be transacted
description String This inputs the optional description for the transaction
orig_ID String This populates the transaction ID of previous transactions (for refunds only)
return_url String The name of the URL used to return to your app (your_app://your_return_function)
sending_app String The name of your app
auto_return String Yes/No string for whether the app should wait for user action before returning to the calling app
email String This input will populate the email field for a customer’s receipt destination
user String Your PayHQ username
password String Your PayHQ password
 

iOS Output Variables

The output variables are values passed back to the app that called to Payfirma, once the transaction is complete. Your app may want to capture the values; transaction results or transaction ID are useful as points of reference.  Although it is not required that the app capture any values, more values means a tighter integration and more business information.

NOTE: If your app is already handling tip, or if the applicable taxes have been calculated into the amount, you should have those respective features turned off within the Payfirma app. Calculating tax or tip before the handoff will cause the amount to then be compounded as it is re-calculated within Mobile HQ.

The return URL will need to be in the format
appname://functionname
in order to correctly relaunch the app – appname will be the text registered in info.plist as the URL scheme to launch the app. Functionname can be anything, but it is helpful for parsing all of the return data.
//
Variable Name Type Description
pf_transaction_type String The transaction type: Sale, Authorize or Refund
pf_amount String The amount of the transaction
pf_tax String The amount of tax to be applied
pf_tip String The tip that is added
pf_total String The combined total of tax, tip and transaction amount
pf_description String The name of your app
pf_masked_card String The entered transaction description
pf_transaction_id String The transaction ID
pf_result String The result of the transactions (Approved or Declined)
pf_merchant_name String The name of the merchant’s business, as entered into the app
pf_timestamp String The time of the transaction: yyyy-mm-dd  hh:mm
//
Variable Name Type Description
pf_transaction_type String The transaction type: Sale, Authorize or Refund
pf_amount String The amount of the transaction
pf_tax String The amount of tax to be applied
pf_tip String The tip that is added
pf_total String The combined total of tax, tip and transaction amount
pf_description String The name of your app
pf_masked_card String The entered transaction description
pf_transaction_id String The transaction ID
pf_result String The result of the transactions (Approved or Declined)
pf_merchant_name String The name of the merchant’s business, as entered into the app
pf_timestamp String The time of the transaction: yyyy-mm-dd  hh:mm
 

Sample Code

You will need to implement one or both of the following functions in the app to delegate support for launching from the URL that the Payfirma app will send back.

The second method (openURL) is supported in iOS 4.2 and later. If you are supporting iOS 4.2 and earlier, you will need to use the handleOpenUrl method.

The code inside will simply parse out all the fields returned in the url into a dictionary.
//Method 1
#pragma mark -- Launching from URL

- (BOOL)application:(UIApplication *)application
handleOpenURL:(NSURL *)url
{
    NSString *query = [url query];
    NSArray *queryPairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary *pairs = [NSMutableDictionary dictionary];
    for (NSString *queryPair in queryPairs){
        NSArray *bits = [queryPair componentsSeparatedByString:@"="];
        if ([bits count] != 2) { continue; }
        NSString *key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
        [pairs setObject:value forKey:key];
    }
    return YES;

}

//Method 2
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation
{
    NSString *query = [url query];
    NSArray *queryPairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary *pairs = [NSMutableDictionary dictionary];
    for (NSString *queryPair in queryPairs){
        NSArray *bits = [queryPair componentsSeparatedByString:@"="];
        if ([bits count] != 2) { continue; }
        NSString *key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
        [pairs setObject:value forKey:key];
    }
    return YES;
} 
 //Method 1
#pragma mark -- Launching from URL

- (BOOL)application:(UIApplication *)application
handleOpenURL:(NSURL *)url
{
    NSString *query = [url query];
    NSArray *queryPairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary *pairs = [NSMutableDictionary dictionary];
    for (NSString *queryPair in queryPairs){
        NSArray *bits = [queryPair componentsSeparatedByString:@"="];
        if ([bits count] != 2) { continue; }
        NSString *key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
        [pairs setObject:value forKey:key];
    }
    return YES;

}

//Method 2
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation
{
    NSString *query = [url query];
    NSArray *queryPairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary *pairs = [NSMutableDictionary dictionary];
    for (NSString *queryPair in queryPairs){
        NSArray *bits = [queryPair componentsSeparatedByString:@"="];
        if ([bits count] != 2) { continue; }
        NSString *key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
        [pairs setObject:value forKey:key];
    }
    return YES;
} 
 

Android Integration

This guide will introduce how any Android app can integrate with Payfirma’s Mobile Payments application, using a handoff (aka hooks) method. We’ve included an example use case, the input/output variables, and sample code.

NOTE: This documentation currently supports our legacy application, Payfirma Mobile Payments, and not Payfirma HQ.  Check back again soon for an updated library.

The legacy Android application is no longer supported.
 
  
 

Android Use Case

Just like our iOS example, we’ll talk about Acme, the invoicing app for businesses creating invoices for their customers. Acme invoices can be sent by email or delivered in person, however, Acme lacks the ability to let businesses accept credit card payments using their app. By integrating with Payfirma, businesses using Acme are able to accept payments using a customer’s credit card.
Android Interaction
  1. A salesperson creates an invoice using the Acme app with an amount and a sale or product description.
  2. The Acme app has a “Pay Now” button that calls the Payfirma app and passes the total, description and optional login credentials.
  3. The Payfirma app is pre-populated with the total, description and any additional data, so the user needs only enter the customer’s credit card information.
  4. The transaction is processed within the Payfirma app and a receipt is sent out.
  5. The Payfirma app automatically closes and reopens the Acme app, passing the transaction ID and transaction status back to the invoicing app.
 
  
 

Android Input Variables

Input variables are used to pass values or information from your app to the Payfirma app, so that it can be pre-populated with the transaction type, amount, and a description. Values do not need to be pre-populated, but they will speed up the process. Without any amounts or information, they will need to be entered manually a second time.

During the transaction and within in the Payfirma app, the user may alter the manually entered or pre-populated variables, such as description or amount; the final values in the Payfirma app are what will be used for the transaction. Each of the variables will need to be preceded by com.payfirma.input. For example:
com.payfirma.input.amount.
NOTE: In the event that the app being used is additionally allowing or tracking login credentials, it is paramount that security measures be taken, so that both usernames as well as passwords are kept protected from outside access or auto-fill functions. 
//
Variable Name Type Description
Transaction Type String This selects the desired transaction: sale, authorize, refund
Amount String This inputs the amount to be transacted
Description String This inputs the optional description for the transaction
Orig_ID String This inputs the transaction ID of the original transaction (for refunds only)
Callback String The name of the intent action used to return your app (such as com.yourapp.return_result)
Sending_app String The name of your app
Email String This input pre-populates the email field to send a receipt to the paying customer
//
Variable Name Type Description
Transaction Type String This selects the desired transaction: sale, authorize, refund
Amount String This inputs the amount to be transacted
Description String This inputs the optional description for the transaction
Orig_ID String This inputs the transaction ID of the original transaction (for refunds only)
Callback String The name of the intent action used to return your app (such as com.yourapp.return_result)
Sending_app String The name of your app
Email String This input pre-populates the email field to send a receipt to the paying customer
 

Android Output Variables

The output variables are values passed back to the app that called to Payfirma, once the transaction is complete. Your app may want to capture the values; transaction results or transaction ID are useful as references.  Although it is not required that the app capture any values, the more values means the tighter the integration.
//
Variable Name Type Description
pf_transaction_type String The transaction type: sale, refund, pre-auth
pf_amount String The transaction amount used
pf_tax String The tax added
pf_tip String The tip added
pf_description String The total with tax and tip
pf_description String The name of your app
pf_masked_card String The description entry
pf_transaction_id String The transaction result (approved or declined)
pf_result String The merchant name as entered in the app
pf_merchant_name String The merchant name as entered in the app
pf_timestamp String The transaction timestamp in yyyy-mm-dd hh:mm format
//
Variable Name Type Description
pf_transaction_type String The transaction type: sale, refund, pre-auth
pf_amount String The transaction amount used
pf_tax String The tax added
pf_tip String The tip added
pf_description String The total with tax and tip
pf_description String The name of your app
pf_masked_card String The description entry
pf_transaction_id String The transaction result (approved or declined)
pf_result String The merchant name as entered in the app
pf_merchant_name String The merchant name as entered in the app
pf_timestamp String The transaction timestamp in yyyy-mm-dd hh:mm format
 

Android Sample Code

You will need to implement one or both of the following functions in the app to delegate support for launching from the URL that the Payfirma app will send back.

Additional Android code samples will become available as we continue to develop the documentation library further. Right now though you can check out our example on GitHub
//A transaction is initiated by calling an intent as described below

Intent intent = new Intent("com.payfirma.makepayment");

intent.putExtra("com.payfirma.input.amount", "1.25");

intent.putExtra("com.payfirma.input.description", "Can of Coke");

intent.putExtra("com.payfirma.input.transaction_type", "SALE");

intent.putExtra("com.payfirma.input.sending_app", "Test App");

intent.putExtra("com.payfirma.input.callback", "com.pftest.receivepaymentresult");

startActivity (intent);

//The calling app will need to have an intent filter defined in its manifest file. This filter should look something like the following:

< intent-filter>
   < action android:name="com.pftest.receivepaymentresult">< /action>
   < category android:name="android.intent.category.DEFAULT">< /category>
< /intent-filter> 
//A transaction is initiated by calling an intent as described below

Intent intent = new Intent("com.payfirma.makepayment");

intent.putExtra("com.payfirma.input.amount", "1.25");

intent.putExtra("com.payfirma.input.description", "Can of Coke");

intent.putExtra("com.payfirma.input.transaction_type", "SALE");

intent.putExtra("com.payfirma.input.sending_app", "Test App");

intent.putExtra("com.payfirma.input.callback", "com.pftest.receivepaymentresult");

startActivity (intent);

//The calling app will need to have an intent filter defined in its manifest file. This filter should look something like the following:

< intent-filter>
   < action android:name="com.pftest.receivepaymentresult">< /action>
   < category android:name="android.intent.category.DEFAULT">< /category>
< /intent-filter>