Onetime Payments

Onetime payments are the instant payment of Checkout API. Start your integration with the following steps once you have product selection step finished in your application:


Build payment page

Payment link can be built by widget object. The configuration difference between single payment methods and all payment methods is the value of ps parameter.

See parameter definition for the requirement and meaning of each parameters while using onetime payments.

<?php
require_once('lib/paymentwall.php');
Paymentwall_Config::getInstance()->set(array(
    'api_type' => Paymentwall_Config::API_GOODS,
    'public_key' => 'YOUR_PROJECT_KEY',
    'private_key' => 'YOUR_SECRET_KEY'
));

$widget = new Paymentwall_Widget(
    'user40012', // uid
    'p1_1', // widget
    array(
        new Paymentwall_Product(
            'product301', // ag_external_id
            9.99, // amount
            'USD', // currencyCode
            'Gold Membership', // ag_name
            Paymentwall_Product::TYPE_FIXED // ag_type
        ) 
    ),
    array(
        'email' => 'user@hostname.com', 
        'history[registration_date]' => 'registered_date_of_user',
        'ps' => 'all', // Replace it with specific payment system short code for single payment methods
        'addtional_param_name' => 'addtional_param_value'
    )
);
echo $widget->getUrl();
?>
var Paymentwall = require('paymentwall');
Paymentwall.Configure(
    Paymentwall.Base.API_GOODS,
    'YOUR_APPLICATION_KEY',
    'YOUR_SECRET_KEY'
);

var widget = new Paymentwall.Widget(
    'user40012', // uid
    'p1_1', // widget 
    [
        new Paymentwall.Product(
            'product301', // ag_external_id
            9.99, // amount
            'USD', // currencycode
            'Gold Membership', // ag_name
            Paymentwall.Product.TYPE_FIXED // ag_type
        )
    ],
    {
    	'email': 'user@hostname.com',
    	'history[registration_date]': 'registered_date_of_user',
    	'ps': 'all', // Replace it with specific payment system short code for single payment methods
    	'additional_param_name': 'additional_param_value'
    }
);
widget.getUrl();
Config.getInstance().setLocalApiType(Config.API_GOODS);
Config.getInstance().setPublicKey("YOUR_APPLICATION_KEY");
Config.getInstance().setPrivateKey("YOUR_SECRET_KEY");

WidgetBuilder widgetBuilder = new WidgetBuilder("USER_ID", "p1_1");

widgetBuilder.setProduct( 
    new ProductBuilder("YOUR_PRODUCT_ID") {
    {
        setAmount(0.99);
        setCurrencyCode("USD");
        setName("YOUR_PRODUCT_NAME");
        setProductType(Product.TYPE_FIXED);
    }
}.build());

widgetBuilder.setExtraParams(new LinkedHashMap<String, String>(){
{
    put("email", "YOUR_CUSTOMER_EMAIL");
    put("history[registration_date]","REGISTRATION_DATE");
    put("ps","all"); // Replace it with specific payment system short code for single payment methods
}
});

Widget widget = widgetBuilder.build();

return widget.getUrl();
require 'paymentwall' # alternatively, require_relative '/path/to/paymentwall-ruby/lib/paymentwall.rb'
Paymentwall::Base::setApiType(Paymentwall::Base::API_GOODS)
Paymentwall::Base::setAppKey('YOUR_APPLICATION_KEY')
Paymentwall::Base::setSecretKey('YOUR_SECRET_KEY')

widget = Paymentwall::Widget.new(
    'user40012',
    'p1_1',
    [
        Paymentwall::Product.new(
            'product301',
            9.99,
            'USD',
            'Gold Membership',
            Paymentwall::Product::TYPE_FIXED
        )
    ],
    {
        'email' => 'user@hostname.com',
        'history[registration_date]' => 'registered_date_of_user',
        'ps' => 'all', # Replace it with specific payment system short code for single payment methods
        'additional_param_name' => 'additional_param_value'
    }
)
puts widget.getUrl()
from paymentwall import *
Paymentwall.set_api_type(Paymentwall.API_GOODS)
Paymentwall.set_app_key('YOUR_PROJECT_KEY')
Paymentwall.set_secret_key('YOUR_SECRET_KEY')

product = Product(
    'product301', # ag_external_id
    9.99,
    'USD', 
    'Gold Membership', 
    Product.TYPE_FIXED 
)

widget = Widget(
    'user40012', # uid
    'p1_1', # widget
    [product], 
    {
        'email' : 'user@hostname.com',
        'history[registration_date]' : 'registered_date_of_user',
        'ps' : 'all', # Replace it with specific payment system short code for single payment methods
        'additional_param_name' : 'additional_param_value'
    }
)
print(widget.get_url())
using Paymentwall;

Paymentwall_Base.setApiType(Paymentwall_Base.API_GOODS);
Paymentwall_Base.setAppKey("YOUR_PROJECT_KEY");
Paymentwall_Base.setSecretKey("YOUR_SECRET_KEY");

List<Paymentwall_Product> productList = new List<Paymentwall_Product>();
Paymentwall_Product product = new Paymentwall_Product(
    "product301", // ag_external_id
    9.99, // amount
    "USD", // currencyCode
    "Gold Membership", // ag_name
    Paymentwall_Product.TYPE_FIXED, //ag_type
);
productList.Add(product);
Paymentwall_Widget widget = new Paymentwall_Widget(
    "user40012", // uid
    "p1_1", // widget
    productList,
    new Dictionary<string, string>() {
        {
            'email' => 'user@hostname.com',
            'history[registration_date]' => 'registered_date_of_user',
            'ps' => 'all', // Replace it with specific payment system short code for single payment methods
            'additional_param_name' => 'additional_param_value'
        }
    }
);
Response.Write(widget.getUrl());

If you would like to redirect the user after a payment is made, you can pass the success_url parameter as optional parameter that will be used as the URL of redirecting displayed to your customer after a payment is made.

You can then embed the payment page into your application by either using iframe or opening it with a new browser window.


Handle pingback

On your server side, put the following code as an online server interface to interact with our Pingback:

<?php
require_once('/path/to/paymentwall-php/lib/paymentwall.php');
Paymentwall_Base::setApiType(Paymentwall_Base::API_GOODS);
Paymentwall_Base::setAppKey('YOUR_PROJECT_KEY'); // available in your Paymentwall merchant area
Paymentwall_Base::setSecretKey('YOUR_SECRET_KEY'); // available in your Paymentwall merchant area

$pingback = new Paymentwall_Pingback($_GET, $_SERVER['REMOTE_ADDR']);
if ($pingback->validate()) {
    $productId = $pingback->getProduct()->getId();
    if ($pingback->isDeliverable()) {
        // deliver the product
    } else if ($pingback->isCancelable()) {
        // withdraw the product
    } else if ($pingback->isUnderReview()) {
        // set "pending" as order status
    }
    echo 'OK'; // Paymentwall expects response to be OK, otherwise the pingback will be resent
} else {
    echo $pingback->getErrorSummary();
}
?>
var Paymentwall = require('paymentwall');
Paymentwall.Configure(
    Paymentwall.Base.API_GOODS,
    'YOUR_PROJECT_KEY',
    'YOUR_SECRET_KEY'
);

var pingback = new Paymentwall.Pingback("query data in pingback request", "ip address of pingback");
if (pingback.validate()) {
    var productId = pingback.getProduct().getId();
    if (pingback.isDeliverable()) {
        // deliver the product
    } else if (pingback.isCancelable()) {
        // withdraw the product
    } 
    console.log('OK'); // Paymentwall expects the string OK in response, otherwise the pingback will be resent
} else {
    console.log(pingback.getErrorSummary());
}
import com.paymentwall.java.*;

Config.getInstance().setLocalApiType(Config.API_GOODS);
Config.getInstance().setPublicKey("YOUR_PROJECT_KEY");
Config.getInstance().setPrivateKey("YOUR_SECRET_KEY");

Pingback pingback = new Pingback(request.getParameterMap(), request.getRemoteAddr());
if (pingback.validate(true)) {
    String goods = pingback.getProductId();
    String userId = pingback.getUserId();
    if (pingback.isDeliverable()) {
        // deliver Product to user with userId
    } else if (pingback.isCancelable()) {
        // withdraw Product from user with userId
    }
    return "OK";
} else {
    return pingback.getErrorSummary();
}
require 'paymentwall' # alternatively, require_relative '/path/to/paymentwall-ruby/lib/paymentwall.rb'
Paymentwall::Base::setApiType(Paymentwall::Base::API_GOODS)
Paymentwall::Base::setAppKey('YOUR_PROJECT_KEY') # available in your Paymentwall merchant area
Paymentwall::Base::setSecretKey('YOUR_SECRET_KEY') # available in your Paymentwall merchant area

pingback = Paymentwall::Pingback.new(request_get_params, request_ip_address)
if pingback.validate()
    productId = pingback.getProduct().getId()
    if pingback.isDeliverable()
        # deliver the product
    elsif pingback.isCancelable()
        # withdraw the product
    end 
    puts 'OK' # Paymentwall expects response to be OK, otherwise the pingback will be resent
else
    puts pingback.getErrorSummary()
end
from paymentwall import *
Paymentwall.set_api_type(Paymentwall.API_GOODS)
Paymentwall.set_app_key('YOUR_PROJECT_KEY') # available in your merchant area
Paymentwall.set_secret_key('YOUR_SECRET_KEY') # available in your merchant area

pingback = Pingback({x:y for x, y in request.args.iteritems()}, request.remote_addr)

if pingback.validate():
    product_id = pingback.get_product().get_id()
    if pingback.is_deliverable():
        # deliver the product
        pass
    elif pingback.is_cancelable():
        # withdraw the product
        pass

    print('OK') # Paymentwall expects response to be OK, otherwise the pingback will be resent

else:
    print(pingback.get_error_summary())
using Paymentwall;

Paymentwall_Base.setApiType(Paymentwall_Base.API_GOODS);
Paymentwall_Base.setAppKey("YOUR_PROJECT_KEY"); // available in your Paymentwall merchant area
Paymentwall_Base.setSecretKey("YOUR_SECRET_KEY"); // available in your Paymentwall merchant area


NameValueCollection parameters = Request.QueryString;
Paymentwall_Pingback pingback = new Paymentwall_Pingback(parameters, HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
if (pingback.validate())
{
    string productId = pingback.getProduct().getId();
    if (pingback.isDeliverable())
    {
        //deliver the product
    }
    else if (pingback.isCancelable())
    {
        //withdraw the product
    }
    Response.Write("OK"); // Paymentwall expects response to be OK, otherwise the pingback will be resent
}
else {
    Response.Write(pingback.getErrorSummary());
}

A pingback request typically contains all the information for you to do the product delivery. As an addition, Terminal3 Payments provides a series of reversed parameters as custom pingback parameters for specific needs, you can also add your own parameters as custom pingback parameter in order to implement parameter transmission.

Below is a sample with default format:

http://www.yourserver.com/pingback_path?uid=pwuser&goodsid=gold_membership&slength=&speriod=&type=0&ref=b1493096790&sign_version=2&sig=d94b23ba8585f29978706dd1b153ead9

After validating the pingback, your server is always expected to be able to proceed the delivery process and respond to it with only OK in the body of response.


Client-side action

In most cases, a complete payment experience is required wherein the end-users can be redirected back to the original application after making a payment.

There would be a link shown up in the payment successful page which is hosted by Terminal3 Payments or our partners if you have success_url presented as optional parameter while building the link of payment page. Your customers are then able to click it and go back to your applications.

Alternatively, client-side callback is suitable if you have additional requirements about client-side actions once a payment is finished.


Relevant topics