npm package: @fctc/minesec-soft
Description: Capacitor plugin for Minesoft Headless SDK
Latest version: 0.0.5

# @fctc/minesec-soft

Capacitor plugin for Minesoft Headless SDK

## Install

```bash
npm install @fctc/minesec-soft
npx cap sync
```

## Configuration

### 1. Setup MineSec GitHub Registry Credentials

Add the following to your global `~/.gradle/gradle.properties` file (NOT in project file):

```properties
MINESEC_REGISTRY_LOGIN=minesec-product-support
MINESEC_REGISTRY_TOKEN=ghp_your_token_here
```

### 2. Configure Android Build

Add to your `android/build.gradle` file:

```gradle
allprojects {
    repositories {
        google()
        mavenCentral()
        def MINESEC_REGISTRY_LOGIN = findProperty("MINESEC_REGISTRY_LOGIN")
        def MINESEC_REGISTRY_TOKEN = findProperty("MINESEC_REGISTRY_TOKEN")

        if (MINESEC_REGISTRY_LOGIN == null) {
            throw new GradleException("""
                Please set your MineSec Github credential in gradle.properties.
                On local machine,
                ** DO NOT ** ** DO NOT ** ** DO NOT **
                Do not put it in the project's file. (and accidentally commit and push)
                ** DO **
                Do set it in your machine's global (~/.gradle/gradle.properties)
            """.trim())
        }

        if (MINESEC_REGISTRY_TOKEN == null) {
            throw new GradleException("MINESEC_REGISTRY_TOKEN is not set in gradle.properties")
        }

        repositories {
            maven {
                name = "MineSecMavenClientRegistry"
                url = uri("https://maven.pkg.github.com/theminesec/ms-registry-client")
                credentials {
                    username = MINESEC_REGISTRY_LOGIN
                    password = MINESEC_REGISTRY_TOKEN
                }
            }
        }
    }
}
```

## Example Usage

```typescript
import { MinesoftHeadless } from '@fctc/minesec-soft';

const paymentNFC = async () => {
  try {
    // Kiểm tra app MSA có cài chưa
    const installCheck = await MinesoftHeadless.isSoftPosInstalled();
    if (!installCheck.installed) {
      openToast({
        message: 'Vui lòng cài đặt ứng dụng MineSec MSA để thanh toán NFC',
        type: 'error',
      });
      return;
    }

    // Gửi giao dịch
    const result = await MinesoftHeadless.transaction({
      type: 'SALE',
      amount: inputValue,
      posMessageId: `${orderID}`,
      autoDismissResult: true,
    });

    // Xử lý kết quả
    if (result.success) {
      openToast({
        message: t('payment:paymentSuccessTitle') || 'Thanh toán thành công!',
        type: 'success',
      });
      goBack();
    } else {
      openToast({
        message: result.message || t('payment:paymentFailedTitle') || 'Thanh toán thất bại!',
        type: 'error',
      });
    }
  } catch (error: any) {
    const msg = error?.message || '';
    let errorMessage = 'Có lỗi xảy ra khi xử lý thanh toán NFC.';

    if (msg.includes('timeout')) errorMessage = 'Timeout khi kết nối MSA.';
    if (msg.includes('network')) errorMessage = 'Lỗi kết nối mạng.';
    if (msg.includes('permission')) errorMessage = 'Thiếu quyền truy cập.';

    openToast({ message: errorMessage, type: 'error' });
  }
};
```

## API

<docgen-index>

* [`isSoftPosInstalled()`](#issoftposinstalled)
* [`warmUp()`](#warmup)
* [`activation(...)`](#activation)
* [`transaction(...)`](#transaction)
* [`enquiryTransactionStatus(...)`](#enquirytransactionstatus)
* [`reloadConfiguration()`](#reloadconfiguration)
* [`enquiryBluetoothStatus()`](#enquirybluetoothstatus)
* [`settlement(...)`](#settlement)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)

</docgen-index>

<docgen-api>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->

MineSoft Headless Plugin Interface

Plugin Capacitor để tích hợp với MineSec SoftPOS app thông qua App-to-App calls.

### isSoftPosInstalled()

```typescript
isSoftPosInstalled() => Promise<InstallationStatusResponse>
```

Kiểm tra xem MSA app đã được cài đặt trên thiết bị chưa

**Returns:** <code>Promise&lt;<a href="#installationstatusresponse">InstallationStatusResponse</a>&gt;</code>

--------------------


### warmUp()

```typescript
warmUp() => Promise<PosResponse>
```

Thực hiện warm up - kiểm tra runtime của MSA app

Warm up sẽ kiểm tra:
- Trạng thái thiết bị
- Trạng thái ứng dụng
- Các điều kiện cần thiết để thực hiện giao dịch

**Returns:** <code>Promise&lt;<a href="#posresponse">PosResponse</a>&gt;</code>

--------------------


### activation(...)

```typescript
activation(options: ActivationRequest) => Promise<PosResponse>
```

Kích hoạt MSA app với activation code

Activation sẽ:
- Kích hoạt app với backend
- Tải cấu hình cửa hàng
- Tải cấu hình EMV
- Tải payment keys

| Param         | Type                                                            | Description                              |
| ------------- | --------------------------------------------------------------- | ---------------------------------------- |
| **`options`** | <code><a href="#activationrequest">ActivationRequest</a></code> | - Activation request với activation code |

**Returns:** <code>Promise&lt;<a href="#posresponse">PosResponse</a>&gt;</code>

--------------------


### transaction(...)

```typescript
transaction(options: TransactionRequest) => Promise<TransactionResponse>
```

Thực hiện giao dịch (SALE, VOID, REFUND, AUTH, AUTH_COMPLETION)

| Param         | Type                                                              | Description           |
| ------------- | ----------------------------------------------------------------- | --------------------- |
| **`options`** | <code><a href="#transactionrequest">TransactionRequest</a></code> | - Transaction request |

**Returns:** <code>Promise&lt;<a href="#transactionresponse">TransactionResponse</a>&gt;</code>

--------------------


### enquiryTransactionStatus(...)

```typescript
enquiryTransactionStatus(options: EnquiryRequest) => Promise<TransactionResponse>
```

Truy vấn trạng thái giao dịch theo transaction ID

| Param         | Type                                                      | Description                     |
| ------------- | --------------------------------------------------------- | ------------------------------- |
| **`options`** | <code><a href="#enquiryrequest">EnquiryRequest</a></code> | - Enquiry request với orgTranId |

**Returns:** <code>Promise&lt;<a href="#transactionresponse">TransactionResponse</a>&gt;</code>

--------------------


### reloadConfiguration()

```typescript
reloadConfiguration() => Promise<PosResponse>
```

Reload cấu hình EMV và payment keys từ backend

**Returns:** <code>Promise&lt;<a href="#posresponse">PosResponse</a>&gt;</code>

--------------------


### enquiryBluetoothStatus()

```typescript
enquiryBluetoothStatus() => Promise<BluetoothStatusResponse>
```

Kiểm tra trạng thái kết nối Bluetooth với thiết bị MPOS D177

**Returns:** <code>Promise&lt;<a href="#bluetoothstatusresponse">BluetoothStatusResponse</a>&gt;</code>

--------------------


### settlement(...)

```typescript
settlement(options: SettlementRequest) => Promise<SettlementResponse>
```

Thực hiện settlement (quyết toán) tất cả các batch

| Param         | Type                                                            | Description                           |
| ------------- | --------------------------------------------------------------- | ------------------------------------- |
| **`options`** | <code><a href="#settlementrequest">SettlementRequest</a></code> | - Settlement request với posMessageId |

**Returns:** <code>Promise&lt;<a href="#settlementresponse">SettlementResponse</a>&gt;</code>

--------------------


### Interfaces


#### InstallationStatusResponse

Response cho check installation

| Prop            | Type                 | Description                      |
| --------------- | -------------------- | -------------------------------- |
| **`installed`** | <code>boolean</code> | true nếu MSA app đã được cài đặt |


#### PosResponse

Response cơ bản từ POS operations

| Prop               | Type                 | Description                                                        |
| ------------------ | -------------------- | ------------------------------------------------------------------ |
| **`success`**      | <code>boolean</code> | true nếu operation thành công                                      |
| **`responseCode`** | <code>string</code>  | Mã phản hồi từ MSA (VD: "00" = success, "51" = insufficient funds) |
| **`message`**      | <code>string</code>  | Thông báo lỗi hoặc thông tin bổ sung                               |


#### ActivationRequest

Request cho activation

| Prop                 | Type                | Description             |
| -------------------- | ------------------- | ----------------------- |
| **`activationCode`** | <code>string</code> | Mã kích hoạt từ MineSec |


#### TransactionResponse

Response chi tiết cho giao dịch

| Prop                | Type                | Description                                     |
| ------------------- | ------------------- | ----------------------------------------------- |
| **`transactionId`** | <code>string</code> | ID giao dịch từ MSA system                      |
| **`amount`**        | <code>string</code> | Số tiền giao dịch                               |
| **`cardNumber`**    | <code>string</code> | Số thẻ đã được mask (VD: "**** **** **** 1234") |
| **`cardType`**      | <code>string</code> | Loại thẻ (VISA, MASTERCARD, AMEX, JCB, etc.)    |
| **`approvalCode`**  | <code>string</code> | Mã phê duyệt từ ngân hàng                       |
| **`timestamp`**     | <code>string</code> | Thời gian giao dịch (ISO 8601 format)           |
| **`merchantId`**    | <code>string</code> | ID merchant                                     |
| **`terminalId`**    | <code>string</code> | ID terminal                                     |
| **`batchNumber`**   | <code>string</code> | Số batch                                        |
| **`invoiceNumber`** | <code>string</code> | Số hóa đơn                                      |
| **`rrn`**           | <code>string</code> | Retrieval Reference Number                      |
| **`stan`**          | <code>string</code> | System Trace Audit Number                       |


#### TransactionRequest

Request cho transaction operations

| Prop                      | Type                                                                | Description                                                   |
| ------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------- |
| **`type`**                | <code><a href="#transactiontype">TransactionType</a></code>         | Loại giao dịch                                                |
| **`amount`**              | <code>string</code>                                                 | Số tiền (required cho SALE, AUTH)                             |
| **`orgTranId`**           | <code>string</code>                                                 | ID giao dịch gốc (required cho VOID, REFUND, AUTH_COMPLETION) |
| **`posMessageId`**        | <code>string</code>                                                 | ID tham chiếu từ POS system (required cho tất cả)             |
| **`autoDismissResult`**   | <code>boolean</code>                                                | Tự động đóng màn hình kết quả và quay về app (default: true)  |
| **`adminPwd`**            | <code>string</code>                                                 | Mật khẩu admin merchant (required cho VOID, REFUND)           |
| **`preferredInstrument`** | <code><a href="#preferredinstrument">PreferredInstrument</a></code> | Phương thức thanh toán ưu tiên (cho QR payment)               |
| **`qrPaymentMethods`**    | <code><a href="#qrpaymentmethod">QRPaymentMethod</a></code>         | Phương thức thanh toán QR cụ thể                              |


#### EnquiryRequest

Request cho enquiry transaction status by transaction ID

| Prop            | Type                | Description               |
| --------------- | ------------------- | ------------------------- |
| **`orgTranId`** | <code>string</code> | ID giao dịch cần truy vấn |


#### BluetoothStatusResponse

Response cho Bluetooth status enquiry

| Prop                | Type                 | Description                           |
| ------------------- | -------------------- | ------------------------------------- |
| **`connected`**     | <code>boolean</code> | true nếu đã kết nối với thiết bị MPOS |
| **`deviceName`**    | <code>string</code>  | Tên thiết bị Bluetooth                |
| **`deviceAddress`** | <code>string</code>  | Địa chỉ MAC của thiết bị              |


#### SettlementResponse

Response cho settlement operation

| Prop                   | Type                | Description                  |
| ---------------------- | ------------------- | ---------------------------- |
| **`batchCount`**       | <code>number</code> | Số lượng batch đã settlement |
| **`totalAmount`**      | <code>string</code> | Tổng số tiền đã settlement   |
| **`transactionCount`** | <code>number</code> | Tổng số giao dịch            |


#### SettlementRequest

Request cho settlement

| Prop               | Type                | Description                 |
| ------------------ | ------------------- | --------------------------- |
| **`posMessageId`** | <code>string</code> | ID tham chiếu từ POS system |


### Type Aliases


#### TransactionType

Loại giao dịch

<code>'SALE' | 'VOID' | 'REFUND' | 'AUTH' | 'AUTH_COMPLETION'</code>


#### PreferredInstrument

Phương thức thanh toán ưu tiên

<code>'QR_MERCHANT_SCAN' | 'QR_GUEST_SCAN'</code>


#### QRPaymentMethod

Phương thức thanh toán QR

<code>'ALIPAY_PLUS' | 'WECHAT_PAY' | 'VNPAY_QR'</code>

</docgen-api>

## POS Response Codes

Tham khảo đầy đủ tại: https://docs.minesecsoftpos.com/suite-app/api-started/pos-response-code

Bảng mã phản hồi thường gặp từ MSA khi thực hiện giao dịch:

| Code | Ý nghĩa                   | Ghi chú                                         |
| ---- | ------------------------- | ----------------------------------------------- |
| 00   | Thành công                | Giao dịch hoàn tất                              |
| 51   | Không đủ tiền             | Thẻ bị từ chối do insufficient funds            |
| 91   | Issuer/Switch inoperative | Lỗi hệ thống ngân hàng/đường truyền             |
| -13  | Pos Message Id duplicate  | `posMessageId` bị trùng; đảm bảo ID là duy nhất |
| 96   | System malfunction        | Lỗi hệ thống, thử lại sau                       |

Lưu ý: Ứng dụng sẽ trả về các trường `success`, `responseCode`, `message`. Luôn kiểm tra `responseCode` để xác định nguyên nhân thất bại và hiển thị thông báo phù hợp.