Documentation
Brick
Brick is Paymentwall's premier credit card solution available for businesses in 200+ countries.
Getting Started
API Credentials
Paymentwall provides you with the following API credentials:
- Public API Key - used for building the Frontend credit card form. This can be publicly available to your end-users.
- Private API Key - used for charging cards from your backend. Keep this private at all times.
A pair of test API keys can be retrieved at the Getting Started page or by Signing Up.
Data Flow
Step 1: Frontend
To charge a credit card, you will first need to collect the credit card details from the end-user and pass them to your backend. Brick helps you to do this in a PCI DSS compliant manner by creating a one-time token that you can further use to charge the card on the Step 2.
Please note that payment pages are required to be loaded via https:// (At least TLSv1.1 is required).
The code sample below will build the credit card form (or add event listeners to your own custom form) and will tokenize the credit card data once the form is submitted and then will send the token to your backend controller specified by action parameter. More details about the client-side library for tokenization can be found in Brick.js documentation.
If you're getting error "Card tokenization failed" - make sure you are testing on https. Known limitation in IE9 and IE10 - the request would not go through if you're testing on http and not https. But in any case, this is the security requirement for going live, but this issue is known to affect testing on development and staging environment.
<script src="https://api.paymentwall.com/brick/build/brick-default.1.5.0.min.js"> </script>
<div id="payment-form-container"> </div>
<script>
var brick = new Brick({
public_key: 'YOUR_PUBLIC_API_KEY', // please update it to Brick live key before launch your project
amount: 9.99,
currency: 'USD',
container: 'payment-form-container',
action: '/YOUR-CHARGE-ACTION',
form: {
merchant: 'YOUR COMPANY',
product: 'Product Name',
pay_button: 'Pay',
show_zip: true, // show zip code field
show_cardholder: true // show card holder name field
}
});
brick.showPaymentForm(function(data) {
// handle success
}, function(errors) {
// handle errors
});
</script>
Step 2: Backend
Below is the code sample for your backend script (billing.php) that uses the credit card token obtained on Step 1 to charge the card. The code sample below uses Paymentwall PHP Library.
require_once 'path/to/lib/paymentwall.php';
Paymentwall_Config::getInstance()->set(array(
'private_key' => 'YOUR_PRIVATE_KEY'
));
$parameters = $_POST;
$cardInfo = array(
'email' => $parameters['email'],
'amount' => 9.99,
'currency' => 'USD',
'token' => $parameters['brick_token'],
'fingerprint' => $parameters['brick_fingerprint'],
'description' => 'Order #123'
);
if (isset($parameters['brick_charge_id']) AND isset($parameters['brick_secure_token'])) {
$cardInfo['charge_id'] = $parameters['brick_charge_id'];
$cardInfo['secure_token'] = $parameters['brick_secure_token'];
}
$charge = new Paymentwall_Charge();
$charge->create($cardInfo);
$responseData = json_decode($charge->getRawResponseData(),true);
$response = $charge->getPublicData();
if ($charge->isSuccessful() AND empty($responseData['secure'])) {
if ($charge->isCaptured()) {
// deliver a product
} elseif ($charge->isUnderReview()) {
// decide on risk charge
}
} elseif (!empty($responseData['secure'])) {
$response = json_encode(array('secure' => $responseData['secure']));
} else {
$errors = json_decode($response, true);
}
echo $response;
Step 3: Testing
Using your Test API Keys available in your merchant area upon activating Brick, you can use one of the cards below for performing tests:
- 4242424242424242
- 4000000000000002
Test CVV/CSC values:
value | outcome |
---|---|
111 | Error: Please ensure the CVV/CVC number is correct before retrying the transaction. |
222 | Error: Please contact your credit card company to check your available balance |
333 | Error: Please contact your credit card company to approve your payment |
555 | Payment is under risk review. Payment is accepted after 2 minutes and respective pingback is sent (type=201). See Preventing Fraud. |
556 | Payment is under risk review. Payment is declined after 2 minutes and respective pingback is sent (type=202). See Preventing Fraud. |
other | Success |
Brick.js
Brick.js is a powerful JavaScript library for building Brick standard credit card forms, tokenizing credit card data, adding submit listeners for tokenizing your custom credit card forms, as well as generating fingerprints for risk scoring.
Brick(options[, type])
Initializes Brick.js
- options - required - object - list of options for Brick.js:
- public_key - required - Your project's Public Key
- container - required - ID of the container where payment form will be placed
- amount - required - Payment amount
- currency - required - Payment currency
- action - required - Pyment form action URL
- form - optional - Payment form configuration object
- id - optional - ID of the payment form. Used for one-line tokenization of custom forms
- merchant - Your company name
- product - Your product name
- pay_button - Text for submit button
- lang - optional - ISO alpha-2 language code to localize the payment form into
- show_cardholder - If set to true, cardholder field will be visible. The result is submitted in brick_firstname and brick_lastname POST parameters. Can be further passed as a customer[firstname] and customer[lastname] into the Charge API
- show_zip - If set to true, zipcode field will be visible. The result is submitted in brick_zip POST parameter. Can be further passed as a customer[zip] into the Charge API for AVS checks
- onTokenized(data) - optional - Callback after custom payment form is tokenized and hidden inputs brick_token and brick_fingerprint are added to the form. Used for one-line tokenization of custom forms.
- data - optional - object - Data format is similar to response from Tokenization API.
- onError(errors) - optional - Callback for errors that occurred during one-line tokenization.
- errors - optional - object - Returns error response object. For example, {"success": "0", "error": {"code": "3004", "message": "Expiration month is invalid"}}
- type - optional - payment form type. Possible value: default, custom
Brick.showPaymentForm(onSuccess, onError)
- onSuccess(data) - required - object - Callback on successful payment
- data - optional - object - Returns object. For example, {"success": "1"}
- onError(errors) - required - Callback when something went wrong
- errors - optional - object - Returns error response object. For example, {"success": "0", "error": {"code": "3004", "message": "Expiration month is invalid"}}
Brick.tokenizeCard(data, callback)
- data - required - Tokenization data. Possible values: HTMLElement | jQuery object | JavaScript Object
// HTMLElement
- document.getElementById('my-payment-form') // JavaScript object
- card_number - Card number
- card_expiration - Card expiration date. Format (MM / YY), for example: "10 / 22"
- card_expiration_month - Card expiration month
- card_expiration_year - Card expiration year
- card_cvv - Card CVV
- callback(data) - required - Callback returning tokenization data on success.
- data - optional - object - Data format is similar to response from Tokenization API
Brick.localize(form, language, options)
Localizes a custom payment form.
- form - required - Payment form HTML Element / jQuery element
- language - optional - string - Language used for translations. Available options: 'de', 'ja', 'fr'. English is set by default.
- options - optional - object - Config for translations. Format: {element: 'label|span|div', position: 'adjacent|inner'}
Expected response types from your backend script:
{"success":1}
- for success{"success":"0","error":{"code":"3004","message":"Expiration month is invalid"}}
- for errors{"success":"0","secure":"..."}
- for 3dsecure scenario
API Reference
Authentication
HTTP Header
All API endpoints except One-time Token expect the Private API key to be sent as custom HTTP header "X-ApiKey". For example, "X-ApiKey: YOUR_PRIVATE_KEY". The API libraries supporting Brick automatically add this API header.
Please note that the Private API key can only be used for server-to-server calls and should never be exposed to end-users. For this reason, One-time Token API accepts Public API key via public_key parameter instead of the Private API key header. Paymentwall is also expecting header Content-Type: application/x-www-form-urlencoded Client-side libraries supporting Brick automatically add X-ApiKey and Content-Type into API requests.
One-time Token
Create a One-time Token
This section describes how to create a one-time token that can be used for charging a card. The one-token is valid for 5 minutes to further perform a charge.
One-time token can be created utilizing Brick.js - see Step 1: Frontend. Alternatively, for merchants who are PCI DSS compliant, the API below can be used.
Request
POST https://pwgateway.com/api/token
(If you're using test keys - POST https://api.paymentwall.com/api/brick/token)
parameter | description |
---|---|
public_key | Merchant's public API key |
card[number] | Card number, digits only |
card[exp_month] | Expiration month, 2 digits from 01 to 12 |
card[exp_year] | Expiration year, 4 digits |
card[cvv] | CVC/CVV, 3-4 digits |
Sample Request
curl https://pwgateway.com/api/token \
-d "public_key=YOUR_PUBLIC_API_KEY" \
-d "card[number]=4000000000000002" \
-d "card[exp_month]=01" \
-d "card[exp_year]=2021" \
-d "card[cvv]=123"
Sample Response - Success
{
"type":"token",
"token":"dc71be025bdcbc2c538e8dca871a8e7b",
"expires_in":290,
"active":1,
"card":{
"type":"Visa",
"last4":"0002",
"bin":"400000",
"exp_month":"01",
"exp_year":"2020",
"issuing_country":"DE"
}
}
Sample Response - Error
{
"type":"Error",
"error":"Card number is empty or invalid",
"code":224
}
One-time Token Error Codes
- 200 - Submited request is empty
- 223 - Expiration date is empty or invalid
- 224 - Card number is empty or invalid
- 225 - CVV is empty or invalid
- 231 - Internal Error
- 700 - Internal Error
- 2111 - Public key is missed or invalid
Charge
Create a Charge
Request
POST https://api.paymentwall.com/api/brick/charge
parameter | required | description |
---|---|---|
amount | yes | Amount to be charged, positive decimal, no commas. E.g. 9999.99 |
currency | yes | Code of the currency to be charged in ISO 4217 format |
browser_ip | yes, if no fingerprint | End-user's IP address |
browser_domain | yes, if no fingerprint | Domain of the website where the payment is originating from |
custom | no | Array of custom parameters, e.g. custom[field1]=1, custom[field2]=2. To receive these values via Pingbacks, please add Custom Pingback Parameter with name=custom and value=OWN |
description | yes | Description for the payment |
yes | End-user's email | |
fingerprint | yes | Paymentwall-generated unique fingerprint of a purchase, used for fraud protection as well as advanced analytics. This field is automatically added as a hidden field to your credit card form when brick.js is used on frontend |
lang | no | ISO alpha-2 language code for email receipt localization, supported languages |
options[capture] | no | Whether or not to immediately capture the charge. Default is true. To not capture, you can pass options[capture]=0. By default merchants have 7 days to either capture or void an non captured authorized charge. |
plan | no | Identifies the product ID, send back as goodsid parameter in Pingbacks |
store_card | no | Whether to tokenize credit card details for subsequent purchases and return Permanent Token parameter in Charge object. Default value is 1 |
token | yes | One-time Token generated for the card or Permanent Token returned in card.token in Charge object |
uid | no | Identifies the internal end-user ID within merchant's system. Used for uid parameter in Pingbacks. If omitted, email is used as uid parameter in Pingbacks |
customer[firstname] | yes | given name of the user |
customer[lastname] | yes | family name of the user |
customer[city] | no | city name |
customer[state] | no | state/province name |
customer[address] | no | address |
customer[country] | no | country code, ISO Alpha-2, e.g. DE |
customer[zip] | no | ZIP/postal code |
secure_redirect_url | no | For 3D Secure payments: URL of the billing page where brick_secure_token and brick_charge_id should be sent via POST after the user completes 3D Secure step. It is recommended to embed brick_fingerprint and brick_token into this URL along with the order ID to subsequently pass them into the Charge |
secure_token | no | 3D Secure token returned to the website after the user completing the 3D Secure step. Required for submitting additional information after 3D Secure step. |
charge_id | no | ID of the original Charge that was sent 3D Secure step. Required for submitting additional information after 3D secure step. |
secure | no | If secure=1 is passed - 3D Secure flow is enforced. |
User Profile API parameters | yes | Parameters for enhanced Risk Scoring, such as customer[lastname], customer[firstname], customer[zip], address, engagement history. Refer to User Profile API |
recurring | no | If this is a charge for recurring billing managed by merchant's scheduling system, recurring=1 has to be passed. This includes the first payment and all subsequent automatic payments. Recurring billing managed by merchant's scheduling system needs to be pre-approved with Paymentwall Merchant Risk Team (mr @ paymentwall.com). |
recurring_id | no | If this is a charge for recurring billing managed by merchant's scheduling system, ID of the first charge needs to be passed as recurring_id. Example: the user first pays (charge ID 123456789) and is charged in a month, then recurring_id=123456789 needs to be passed (along with recurring=1). |
pingback_url | no | Optional URL of pingback listener script where pingbacks should be sent. Overrides the default Pingback URL set up in Project Settings inside of merchant account. Takes effect only if activated for the merchant account per request. |
Sample Request
curl https://api.paymentwall.com/api/brick/charge \
-H "X-ApiKey: [YOUR_PRIVATE_KEY]" \
-d "token=[TOKEN]" \
-d "amount=9.99" \
-d "currency=USD" \
-d "email=user@host.com" \
-d "fingerprint=[FINGERPRINT_BY_BRICK.JS]" \
-d "description=TestItem"
Response
Returns a Charge object
{
"object":"charge",
"id":"52859",
"created":1392053429,
"amount":"9.99",
"currency":"USD",
"refunded":false,
"captured":false,
"risk":"approved",
"card":{
"last4":"4242",
"type":"Visa",
"exp_month":"12",
"exp_year":"2019",
"country":null,
"name":"John Doe",
"token":"2857a8cefec761ef7cdb3f97abf4c7b1"
},
"secure":false,
"support_link":"https://api.paymentwall.com/api/account/email-viewer?...",
"paid_amount":"9.99",
"paid_currency":"USD", // may vary from the requested value in case the user is billed in a different currency
"drm_key":"xyzw-xyzw-xyzw-xyzw" // optional field if DRM functionalities are used
}
3D Secure
If 3D Secure step is required, the following response is returned as a response to create Charge request. User then needs to be presented with an HTML page where this form is automatically submitted, so that he can complete the 3D Secure step. Developers need to embed this formHTML into the page's HTML. The form will submit itself.
{
"secure":{"formHTML":"..."}
}
After completing the 3D Secure step, the user will be redirected back to the website with parameters brick_charge_id and brick_secure_token that need to be appended to the request parameters of the original Charge request. Brick 3D Secure data flow diagram.
Default Form
If you're using default brick.js form, it takes care of this step itself and re-submits the request to your backend script.
Custom Form / Redirect Flow
You should pass secure_redirect_url in the Charge request where the user will be redirected after completing the 3D Secure step and where parameters brick_secure_token and brick_charge_id will be passed via POST. Once you get the 3D Secure form HTML, you can submit the form via something like the following code in PHP.
echo '<div id="3ds_form_container">' . $responseData['secure']['formHTML'] . '</div><script>document.getElementById("3ds_form_container").getElementsByTagName("form")[0].submit();</script>';
Once the user completes the step, he will be redirected back to secure_redirect_url from where you can complete the Charge. brick_fingerprint and brick_token of the original request should be embedded into secure_redirect_url along with the order ID, so that they can be subsequently passed into the Charge.
Custom Form / Popup Flow
To open the 3D Secure form, you can open a popup via window.open
and submit the 3D Secure form into that popup via target
attribute of the form.
Capturing the 3D Secure step completion
You can , and catch the 3D Secure step completion into the original via window.postMessage
using the following message format: {"event":"3dSecureComplete","data":{"secure_token":"...","charge_id":"..."}}
.
Preventing Fraud
Paymentwall has an in-house risk scoring system assesing the risk level of every transaction in realtime based on various such as velocity metrics, geolocation, transaction history, engagement, device information. Paymentwall also has a 24/7 in-house team of risk analysts that perform agent review of transactions with high risk score on behalf of merchants. To ensure that Paymentwall's risk engine has all the necessary data to score transactions accurately, please ensure to pass as much User Profile API information as possible along with every Charge or Subscription API creation request.
In case a payment is currently under risk review by Paymentwall, the following fields will be returned in the charge object among the others:
{
...
"risk":"pending",
"captured":false,
...
}
At the same time, pingback with type=200 is sent to your server letting you know that the payment is pending risk review.
Once the risk review is over (which normally takes only a few minutes), Paymentwall will send a Pingback with the respective decision: type=201 if the payment is accepted; type=202 if the payment is declined.
You can use Test CVV numbers 555 and 556 to emulate accepted and declined after risk review scenarios, respectively.
Storing a card after a Charge
If you want to store the credit card for future use, you can store the permanent token (card.token field of charge response object) and use it for a new charge later on. For this you can use the following example utilizing Paymentwall PHP library:
// Library initialization section
$charge = new Paymentwall_Charge(/* charge details */);
if ($charge->isSuccessful()) {
store($charge->card->token);
}
Please note that during charge you can pass options[capture]=0, thus only creating a temporary authorization without charging the funds from the user's card. You can then void the charge and return funds to the user.
You can pass amount=0 for zero authorization so that the user is not charged, however this may be declined by some issuing banks depending on where your business entity is registered. Please contact your account manager for the possibility of activating zero authorization.
Get Charge details
Request
GET https://api.paymentwall.com/api/brick/charge/$id
Response
Charge object
Refund a Charge
Request
POST https://api.paymentwall.com/api/brick/charge/$id/refund
Response
Charge object
Capture a Charge
Request
POST https://api.paymentwall.com/api/brick/charge/$id/capture
Response
Charge object
Void a Charge
Request
POST https://api.paymentwall.com/api/brick/charge/$id/void
Code example using Paymentwall PHP library.
// Library initialization section
$charge = new Paymentwall_Charge('CHARGE_ID');
$charge->void();
Response
Charge object
Subscription
Create a Subscription
Request
POST https://api.paymentwall.com/api/brick/subscription
parameter | required | description |
---|---|---|
amount | yes | Amount to be charged, positive decimal, no commas. E.g. 9999.99 |
currency | yes | Code of the currency to be charged in ISO 4217 format |
custom | no | Array of custom parameters, e.g. custom[field1]=1, custom[field2]=2. To receive these values via Pingbacks, please add Custom Pingback Parameter with name=custom and value=OWN |
description | yes | Description for the payment |
yes | End-user's email | |
fingerprint | yes | Paymentwall-generated unique fingerprint of a purchase, used for fraud protection as well as advanced analytics. This field is automatically added as a hidden field to your credit card form when brick.js is used on frontend |
lang | no | ISO alpha-2 language code for email receipt localization, supported languages |
plan | yes, if trial | Identifies the product ID, send back as goodsid parameter in Pingbacks |
period | yes | day/week/month/year |
period_duration | yes | Number of periods mentioned in the period parameter. By default minimum duration for recurring is 3 days. This can be adjusted by contacting devsupport@paymentwall.com |
token | yes | One-time Token generated for the card or Permanent Token returned in card.token in Charge object |
trial | optional | Trial subscription details array |
trial[amount] | yes, if trial | Trial amount. Free trials are also supported (to have free trials active for your account please contact devsupport@paymentwall.com) |
trial[currency] | yes, if trial | Trial currency |
trial[period] | yes, if trial | Trial recurring period |
trial[period_duration] | yes, if trial | Trial recurring period duration. By default minimum duration is 3 days. This can be adjusted by contacting devsupport@paymentwall.com |
uid | no | Identifies the internal end-user ID within merchant's system. Used for uid parameter in Pingbacks. If omitted, email is used as uid parameter in Pingbacks |
User Profile API parameters | yes | Parameters for enhanced Risk Scoring, such as lastname, firstname, address, engagement history. Refer to User Profile API |
pingback_url | no | Optional URL of pingback listener script where pingbacks should be sent. Overrides the default Pingback URL set up in Project Settings inside of merchant account. Takes effect only if activated for the merchant account per request. |
Response
Returns a Subscription object
{
"object":"subscription",
"id":"VCBZT392SW",
"period":"day",
"period_duration":3,
"payments_limit":122,
"is_trial":0,
"started":1,
"expired":0,
"active":1,
"date_started":1419525232,
"date_next":1419784432,
"trial":{
"object":"subscription",
"id":"VCBZT392SW",
"period":"day",
"period_duration":1,
"payments_limit":1,
"is_trial":1,
"started":1,
"expired":1,
"active":0,
"date_started":1419438832,
"date_next":1419525232,
}
"charges":[
49393608,
49393609
]
}
Every time a user is charged, a Pingback will be sent to your servers using the URL specified as the Pingback URL in your project settings.
3D Secure - Subscriptions
For Subscriptions, 3D Secure is supported similarly to 3D Secure in Charges. If you pass secure=1 to force 3D Secure or if 3D Secure is activated by default, this will return
{
"secure":{"formHTML":"..."}
}
For more details refer to 3D Secure for Charges.
Get Subscription details
Request
GET https://api.paymentwall.com/api/brick/subscription/$id
Response
Subscription object
Cancel a Subscription
Request
POST https://api.paymentwall.com/api/brick/subscription/$id/cancel
Response
Subscription object
Error
Error Object
{
"type":"Error",
"error":"Wrong charge amount",
"code":3002
}
In case of an error, Paymentwall responds back with 4xx HTTP Response Status Codes. For example, error 4007 (API key is invalid) is sent back with 401 status code. In order to fetch the response body for error object, please make sure your application is able to read response body for requests that return 4xx status code.
List of Error Codes
- 1000 Internal error
- 1001 Project isn't loaded, please double-check the API keys
- 1003 Requested payment method is not active for the given project - contact devsupport@paymentwall.com
- 1004 Requested payment method is not active for the given country - contact devsupport@paymentwall.com
- 3000 Charge not found
- 3001 Permission denied
- 3002 Wrong charge amount
- 3003 Card number is missing or invalid
- 3004 Expiration month is invalid
- 3005 Expiration year is invalid
- 3006 Expiration date is invalid
- 3007 Currency is missing or invalid
- 3008 Please fill in all required fields
- 3009 Please correct the billing address and retry the transaction
- 3010 Please contact your credit card company to approve your payment
- 3011 Please contact your credit card company to check your available balance
- 3012 Transaction was declined
- 3013 Transaction was declined due to issues with the card
- 3014 Wrong CVV
- 3016 Transaction was declined due to failed 3D Secure check
- 3101 Please verify the credit card number and retry the transaction
- 3102 You submitted an expired credit card number. Please ensure the credit card is valid
- 3103 You have submitted a card which is not supported. Please, use Visa, MasterCard, AmEx or Discover credit card
- 3104 Country of the card is not supported
- 3111 Token was not found
- 3112 One-time token is invalid
- 3113 Test credentials are invalid
- 3114 Token was deleted
- 3115 Charge amount is too small. Default minimum is 0.50 USD. Please contact devsupport@paymentwall.com to adjust
- 3116 Charge amount is too high. Default maximum is 500 USD. Please contact devsupport@paymentwall.com to adjust
- 3200 Please retry the transaction or use another credit card
- 3201 The charge has already been fully refunded
- 3202 You can't cancel this transaction
- 3203 This charge is not found or already captured
- 3204 You can't refund this transaction
- 3205 Duplicate charge
- 3206 Authorization for this card has expired
- 3207 This charge is pending risk review
- 3301 Please check first name
- 3302 Please check last name
- 3303 Please check address
- 3304 Please check city
- 3305 Please check state
- 3306 Please check Zip / Postal Code
- 3401 Wrong subscription period
- 3402 Subscription not found
- 3403 Wrong subscription period duration
- 3404 Some subscription trial parameters are missing
- 3405 Subscription trial period is invalid
- 3406 Subscription trial period duration is invalid
- 3407 Subscription trial amount is invalid
- 3408 Number of repeated payments in case of subscription failure is invalid
- 4004 Undefined method
- 4005 Request is empty
- 4006 API key is not provided
- 4007 API key is invalid
- 4008 Decryption failed
- 4010 This API is not activated for the given project
- 5000 Customer is not allowed to pay