# 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

```java
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](#D4xuN) | Transaction information. | Optional |
| riskControlInfo | [RiskControlInfo](#mB5N0) | Risk control information. | Optional |

### TransactionInfo

```java
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

```java
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](#f5wIB) | 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

```java
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;
            }
        }
    }
}

```