In-App Payments SDK: Cookbook

Connect to a Backend Service

Connect a mobile app using the In-App Payments SDK to a server backend.

In-App Payments SDK
Transactions API
Java (Android)

Before you start

You have completed the In-App Payments SDK setup guide.

The In-App Payments SDK has a default SQUIPTheme object, which provides UI styling properties for customizing the card entry view controller. This recipe gives the steps to customize the default styling of the SDK.

Step 1: Set up a connection to a payment processing backend

To validate and process the nonce returned by the SDK CardEntry object, you must send it to a backend service that uses Connect payment APIs to capture payment.

To set up the backend connection, build a Retrofit object and configure it with the base URL for your backend service:

public class ConfigHelper {

  private static final String CHARGE_SERVER_HOST = "REPLACE_ME";
  private static final String CHARGE_SERVER_URL = "https://" + CHARGE_SERVER_HOST + "/";

  public static boolean serverHostSet() {
    return !CHARGE_SERVER_HOST.equals("REPLACE_ME");

  public static Retrofit createRetrofitInstance() {
    return new Retrofit

Step 2: Define a REST interface for POST requests

public interface ChargeService {
  Call<Void> charge(@Body ChargeRequest request);

  class ChargeErrorResponse {
    String errorMessage;

  class ChargeRequest {
    final String nonce;

    ChargeRequest(String nonce) {
      this.nonce = nonce;

Step 3: Make calls with the REST interface

To use your REST interface, create a Call<ChargeResult> implementation that will package and send requests to the payment processing backend:

public class ChargeCall implements Call<ChargeResult> {

  public static class Factory {
    private final ChargeService service;
    private final Converter<ResponseBody, ChargeService.ChargeErrorResponse> errorConverter;

    public Factory(Retrofit retrofit) {
      service = retrofit.create(ChargeService.class);
      Annotation[] noAnnotations = {};
      Type errorResponseType = ChargeService.ChargeErrorResponse.class;
      errorConverter = retrofit.responseBodyConverter(errorResponseType, noAnnotations);

    public Call<ChargeResult> create(String nonce) {
      return new ChargeCall(this, nonce);

  private final ChargeCall.Factory factory;
  private final String nonce;
  private final retrofit2.Call<Void> call;

  private ChargeCall(ChargeCall.Factory factory,
      String nonce) {
    this.factory = factory;
    this.nonce = nonce;
    call = factory.service.charge(new ChargeService.ChargeRequest(nonce));

  public ChargeResult execute() {
    Response<Void> response;
    try {
      response = call.execute();
    } catch (IOException e) {
      return ChargeResult.networkError();
    return responseToResult(response);

  public void enqueue(sqip.Callback<ChargeResult> callback) {
    call.enqueue(new Callback<Void>() {
      public void onResponse(@NonNull retrofit2.Call<Void> call, @NonNull Response<Void> response) {

      public void onFailure(@NonNull retrofit2.Call<Void> call, Throwable throwable) {
        if (throwable instanceof IOException) {
        } else {
          throw new RuntimeException("Unexpected exception", throwable);

  //TODO: Define the ChargeResult method in step 4.

    //additional required Call<ChargeResult> methods

Step 4: Handle the backend results

Define a ChargeResult object and act on the results:

private ChargeResult responseToResult(Response<Void> response) {
  if (response.isSuccessful()) {
    return ChargeResult.success();
  try {
    //noinspection ConstantConditions
    ResponseBody errorBody = response.errorBody();
    ChargeService.ChargeErrorResponse errorResponse = factory.errorConverter.convert(errorBody);
    return ChargeResult.error(errorResponse.errorMessage);
  } catch (IOException exception) {
    return ChargeResult.networkError();

Contact Developer Support, join our Slack channel, or ask for help on Stack Overflow