Alipay+ DocsAlipay+ Docs

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

copy
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

TransactionInfo

Transaction information.

Optional

riskControlInfo

RiskControlInfo

Risk control information.

Optional

TransactionInfo

copy
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

copy
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

AppPermitResult

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

copy
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;
            }
        }
    }
}