TransactionPermit
The TransactionPermit SPI controls transaction authorization. It enables you to make final authorization decisions during the transaction process based on specific criteria.
Method Signature
interface TransactionPermit {
AppPermitResult isAllowed(boolean authBefore, @Nullable TransactionInfo transactionInfo, @Nullable RiskControlInfo riskControlInfo);
}Request parameters
Parameters for isAllowed function:
Item | Type | Description | Required |
authBefore | boolean | Whether authentication occurred within 30 seconds prior to the transaction. | Required |
transactionInfo | Transaction information. | Optional | |
riskControlInfo | Risk control information. | Optional |
TransactionInfo
byte[] getCurrencyCode(); //Currency, in accordance with ISO standards
byte[] getAuthorizedAmount(); //Transaction amount
/* Transaction Range: Follow the card group specification
LOW_VALUE, Low value transaction
HIGH_VALUE, High value transaction
UNKNOWN;
*/
TransactionRange getTransactionRange();
/* Transaction Type: Follow ISO 8583
PURCHASE, purchase
TRANSIT, transportation scenario
*/
RichTransactionType getRichTransactionType();RiskControlInfo
public RiskControlInfo(boolean riskControlDecision) {
this.riskControlDecision = riskControlDecision;
}
private boolean riskControlDecision;
public boolean isRiskProceed() {
return riskControlDecision;
}
public void setRiskControlDecision(boolean riskControlDecision) {
this.riskControlDecision = riskControlDecision;
}Response parameters
Item | Type | Description |
result | Whether the transaction is permitted. |
AppPermitResult
Item | Description |
PROCEED | Transaction permitted. |
DECLINE | Transaction rejected. |
NEED_AUTH | User authentication needed. |
APP_CUSTOM_DECLINE_1 | The transaction was declined for MPP custom reason 1. |
APP_CUSTOM_DECLINE_2 | The transaction was declined for MPP custom reason 2. |
APP_CUSTOM_DECLINE_3 | The transaction was declined for MPP custom reason 3. |
APP_CUSTOM_DECLINE_4 | The transaction was declined for MPP custom reason 4. |
APP_CUSTOM_DECLINE_5 | The transaction was declined for MPP custom reason 5. |
Sample
public class TransactionAuthInProgress implements TransactionPermit {
private Context context;
private SharedPreferencesUtil sharedPreferencesUtil;
public static final String CURRENCY_CODE = "currencyCode";
public static final String AUTHORIZED_AMOUNT = "authorizedAmount";
private static final String IS_3TAB_PAGE = "is_3tab_page";
private static final String IS_3TAB_PAGE_Switch = "is_3tab_page_switch";
public TransactionAuthInProgress(Context context) {
this.context = context;
sharedPreferencesUtil = new SharedPreferencesUtil(context);
}
@Override
public AppPermitResult isAllowed(boolean authBefore, TransactionInfo transactionInfo, @NonNull RiskControlInfo riskControlInfo) {
Log.d("PERMIT", "authBefore: " + authBefore + ", riskControlInfo.isRiskProceed(): " + riskControlInfo.isRiskProceed());
byte[] currencyCode = transactionInfo.getCurrencyCode();
byte[] authorizedAmount = transactionInfo.getAuthorizedAmount();
Log.d("20241113", "currencyCode: " + currencyCode + ", authorizedAmount: " + authorizedAmount);
boolean is3tabSwitch = sharedPreferencesUtil.getBool(IS_3TAB_PAGE_Switch);
boolean is3TabPage = sharedPreferencesUtil.getBool(IS_3TAB_PAGE);
Log.d("20241231", "currencyIs3TabPage: " + is3TabPage );
if (currencyCode != null) {
String currencyCodeString = HCEApduCommandMock.t(currencyCode);
sharedPreferencesUtil.saveString(CURRENCY_CODE, currencyCodeString);
}
if (authorizedAmount != null) {
String authorizedAmountString = HCEApduCommandMock.t(authorizedAmount);
sharedPreferencesUtil.saveString(AUTHORIZED_AMOUNT, authorizedAmountString);
}
if (!is3tabSwitch || transactionInfo.getRichTransactionType() == RichTransactionType.TRANSIT) {
return (riskControlInfo.isRiskProceed())? AppPermitResult.PROCEED :AppPermitResult.NEED_AUTH;
} else {
if (is3TabPage) {
return AppPermitResult.PROCEED;
} else {
return AppPermitResult.DECLINE;
}
}
}
}