# 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
- 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.
- 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";
}