Paymentwall website uses cookies to store your browsing preferences on your device. However, cookies do not collect personal information.

For more information about how we use cookies, check our cookie policy

Close

Documentation

New Documentation Getting Started API Libraries APIs Checklists Flows Integrations Mobile SDKs Reference Smart TV SDK SpiderPipe Testing Payments
Contacts
If you still have questions regarding integration, please email us at devsupport@paymentwall.com

Brick

Brick is Paymentwall's premiere 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

Link to data flow chart.

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 Step 2.
Please note that payment pages are required to be loaded via https:// (At least TLSv1.1 is recommended).
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/brick.1.4.js"> </script>
<div id="payment-form-container"> </div>
<script>
  var brick = new Brick({
    public_key: 'YOUR_PUBLIC_API_KEY',
    amount: 9.99,
    currency: 'USD',
    container: 'payment-form-container',
    action: 'billing.php',
    form: {
      merchant: 'Merchant Name',
      product: 'Product Name',
      pay_button: 'Pay',
      zip: true
    }
  });

  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 pyment 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
      • zip - If set to true, zipcode field will be visible. Result is submitted in brick_zip POST parameter. Can be further passed as 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"
  }
}

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
email 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. 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: user first pays (charge ID 123456789) and is charged in a month, then recurring_id=123456789 needs to be passed.

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
email 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

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
This page needs JavaScript
Your browser is
not supported anymore.
Please update to the more recent one.
This page needs JavaScript
This page needs JavaScript.
Please enable it in your browser settings and try again.