# Payment Hooks

Poynt Payment Fragment provides a set of hooks to intercept payments by allowing developers to include added value services in their applications such as loyalty, and discounts, among others. This document describes how a developer can register and use the payment hooks.

TIP

We have also designed a Sample Payment Hooks App (opens new window) with detailed information regarding the implementation and usage of payment hooks.

Payment hooks allow developers to build applications that hook into the payment flow without having to open the application manually. This creates a better user experience and few interactions per transaction.

As an example, if you would like to provide loyalty rewards for every customer, you add points based on the amount and identify the customer using the unique card hash provided after the card is swiped.

NOTE

Below is the minimum OS version required to implement and use payment hooks

Device OS Version Required
Poynt 5 1.19.7-56-101
Smart Terminal V1 1.19.7-57-105
Smart Terminal V2 1.19.7-54-98

# Prerequisites

  • To integrate with Payment Hooks, please keep in mind there is a minimum SDK version required as shown below.
implementation 'co.poynt.api:android-api-model:1.2.140'
implementation 'co.poynt.android.sdk:poynt-sdk:1.2.44'

# Integration

  1. Create a service that implements IPoyntPaymentHooks (opens new window).
public class SamplePaymentHooksService extends Service {
    public SamplePaymentHooksService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private final IPoyntPaymentHooks.Stub mBinder = new IPoyntPaymentHooks.Stub() {
        @Override
        public void onEvent(@PaymentHookEvent.Type String eventType, Payment payment, @Nullable Transaction transaction, @Nullable Bundle bundle, IPoyntPaymentHooksListener listener) throws RemoteException {

        	/**
        	 * put you code here
        	 * or use default behavior
             * IMP NOTE: IF YOU RECEIVE AN EVENT THAT YOU DO NOT RECOGNIZE, YOU MUST
             * CALL ONCONTINUE() CALLBACK. THIS IS IMPORTANT FOR BACKWARD/FORWARD
             * COMPATIBILITY
        	 */
          listener.onContinue();
        }
    };
}

Note

Always call the listener.onContinue() by default if there is no action needed, failure to do this can result in breaking the ability to transact.

  1. Specify the configuration in the payment_hooks_capability.xml file and add it to your Android.manifest file.

Payment Hooks Capability File

<?xml version="1.0" encoding="utf-8"?>
<capability>
  <!-- Your App ID same as your package name-->
  <appid>com.poynt.samples.paymenthooks</appid>

	<!-- DO NOT CHANGE-->
  <type>PAYMENT_HOOKS</type>

  <!-- descriptive name of this capability -->
  <provider>Sample Hooks</provider>
</capability>

Android Manifest File

........
<service
  android:name=".SamplePaymentHooksService"
  android:enabled="true"
  android:exported="true">
  <intent-filter>
      <action android:name="co.poynt.os.services.v1.IPoyntPaymentHooks" />
  </intent-filter>
  <meta-data
      android:name="co.poynt.os.service.capability"
      android:resource="@xml/payment_hooks_capability" />
</service>

# Payment Hooks Listener

The payment hooks listener provides multiple ways to pass back information or to resume the flow.

interface IPoyntPaymentHooksListener{

    /**
     * Call this listener when you want to send updated payment object
     * @param payment
     */
    void updatePayment(Payment payment);

    /**
     * Call this listener when you want to use default flow
     */
    void onContinue();

    /**
     * Call this listener when you want to start an activity
     * @param intent
     */
    void onLaunchActivity(Intent intent);

}

# Events & Extras

Payment hook events are triggered for sales, refunds, voids and authorizations.

The event types that are currently supported include the following:

public class PaymentHookEvent {
    @Retention(RetentionPolicy.SOURCE)
    @StringDef({
            PAYMENT_STARTED,
            PAYMENT_CANCELED,
            PAYMENT_RESTARTED,
            PAYMENT_METHOD_SELECTED,
            PAYMENT_AUTHORIZED,
            PAYMENT_FAILED,
            PAYMENT_VOIDED,
            PAYMENT_REFUNDED})
    public @interface Type {
    }

    /**
     * Event will be called just after opening payment fragment.
     */
    public static final String PAYMENT_STARTED = "PAYMENT_STARTED";

    /**
     * Event will be called when transaction is canceled after tap on "Cancel" button
     */
    public static final String PAYMENT_CANCELED = "PAYMENT_CANCELED";

    /**
     * Event will be called when transaction is restarted after tap on "Retry" button
     */
    public static final String PAYMENT_RESTARTED = "PAYMENT_RESTARTED";

    /**
     * Event will be called when payment method has been selected:
     * CASH
     * CARD
     * MANUAL_ENTRY
     */
    public static final String PAYMENT_METHOD_SELECTED = "PAYMENT_METHOD_SELECTED";

    /**
     * Event will be called after online authorization.
     * CARD and MANUAL_ENTRY only
     */
    public static final String PAYMENT_AUTHORIZED = "PAYMENT_AUTHORIZED";

    /**
     * Event will be called when transaction has failed (example: offline decline)
     */
    public static final String PAYMENT_FAILED = "PAYMENT_FAILED";

    /**
     * Event will be called when transaction is voided
     */
    public static final String PAYMENT_VOIDED = "PAYMENT_VOIDED";

    /**
     * Event will be called when transaction is refunded
     */
    public static final String PAYMENT_REFUNDED = "PAYMENT_REFUNDED";
}

Hook events are accompanied by a bundle with additional data based on the hook type.

The available extras included in the bundle

TIP

Not all of the extras are available with all the hooks

public static final class HooksExtras {
        public static final String PAYMENT_TYPE = "PAYMENT_TYPE";
        public static final String PAYMENT = "payment";
        public static final String TRANSACTION = "transaction";
}

public static final class CardExtras {
        public static final String SERVICE_CODE = "SERVICE_CODE";
        public static final String CARDHOLDER_NAME = "CARDHOLDER_NAME";
        public static final String APP_EXPIRATION_DATE = "APP_EXPIRATION_DATE";
        public static final String PAN_LAST_4 = "PAN_LAST_4";
        public static final String CARD_BIN_RANGE = "CARD_BIN_RANGE";
        public static final String ACQUIRER_ID = "ACQUIRER_ID";
        public static final String AID_TERMINAL = "AID_TERMINAL";
        public static final String APPLICATION_LABEL = "APPLICATION_LABEL";
        public static final String PAN_SEQUENCE_NUMBER = "PAN_SEQUENCE_NUMBER";
        public static final String ISSUER_COUNTRY_CODE = "ISSUER_COUNTRY_CODE";
        public static final String ENCRYPTED_PAN = "ENCRYPTED_PAN";
        public static final String ENCRYPTED_TRACK = "ENCRYPTED_TRACK";
        public static final String ISSUER_CODE_TABLE_INDEX = "ISSUER_CODE_TABLE_INDEX";
        public static final String APP_PREFERRED_NAME = "APP_PREFERRED_NAME";
        public static final String KEY_IDENTIFIER = "KEY_IDENTIFIER";
        public static final String APPLICATION_CURRENCY_CODE = "APPLICATION_CURRENCY_CODE";
        public static final String PAN_HASH = "PAN_HASH";
}
Last Updated: 10/4/2022, 8:01:35 AM