flutter_pinelabs

This project provides interface to access the Pinelabs API. Using the android implementation of pinelabs device rather than the hybrid application approach. It's an honest attempt to provide a simple and easy to use interface to access the pinelabs API.

Pinelabs Request and Response

doTransaction

As stated by pinelabs.

This API will be called when the Billing App completes the product selection and is ready to accept payment from the customer. Billing App will add all required tender options in its App, and call this API with specific tender such as Sale, Prepaid redeem etc.
This API can also be used for Load, Activation, Void transaction, etc. refer Transaction Types for complete list of transactions supported.

This API takes the following parameters:

  1. transactionType: Which can be any option from the enum TransactionType. Currently supports cash, card, upi and bharatqr.
  2. billingRefNo: This is the reference number that is generated by the Billing App. This is used to identify the transaction. It can be null.
  3. paymentAmount: This is the amount that is to be paid. This is in the currency of the Billing App.
  4. overrideHeader: This is the header that is to be used for the transaction. This is used to override the header that is configured while initializing the flutter_pinelabs. This can be null only if header was provided during initialization.
  5. mobileNumberForEChargeSlip: Mobile number on which eChargeSlip can be sent. This feature must be enabled by pinelabs before this can be used. This can be null.
// Snippet to implement doTransaction

final response = await _flutterPinelabsPlugin.doTransaction(
      transactionType: TransactionType.cash,
      billingRefNo: '12345',
      paymentAmount: 32.52,
      overrideHeader: HeaderModel(
        applicationId: 'your application id issued by pinelabs.',
        methodId: '1001',
        versionNo: '1.0',
        userId: 'logged in user id. nullable',
      ),
      mobileNumberForEChargeSlip: '9876543210',
    );

  /// provides ResponseModel in return which contains the response from the pinelabs device.
  setState(() {
    _responseMessage = response?.responseMsg ?? '';
  });

A ResponseModel is returned in response to the doTransaction call. Which will store:

  1. header: This is the header that is returned by pinelabs.
  2. responseCode: This is the response code that is returned by pinelabs. 0 when success other codes are mentioned in pinelabs official docs.
  3. responseMsg: This is the response message that is returned by pinelabs.
  4. rawResponse: Json string that is returned by pinelabs. The above values are extracted from this string and stored in the ResponseModel.

Request to the device in json format when the above method is called will be as follows:

{
  "Header": {
    "ApplicationId": "your application id issued by pinelabs.",
    "UserId": "1",
    "MethodId": "1001",
    "VersionNo": "1.0"
  },
  "Detail": {
    "TransactionType": "4001",
    "BillingRefNo": "12345",
    "PaymentAmount": "32.52",
    "MobileNumberForEChargeSlip": "9876543210"
  }
}

getUpiStatus

This method can be used to fetch the status of a given upi transaction. Provide billingRefNo and amount of the UPI payment whose status needs to be checked.

This API takes the following parameters:

  1. billingRefNo: This is the reference number that is generated by the Billing App. This is used to identify the transaction. It can be null.
  2. paymentAmount: This is the amount that is to be paid. This is in the currency of the Billing App.
  3. overrideHeader: This is the header that is to be used for the transaction. This is used to override the header that is configured while initializing the flutter_pinelabs. This can be null only if header was provided during initialization.
// Snippet to implement sendRequest
final response = await _flutterPinelabsPlugin.getUpiStatus(
      paymentAmount: [Amount],
      billingRefNo: [BillingNumber],
      overrideHeader: HeaderModel(
        applicationId: 'your application id issued by pinelabs.',
        methodId: '1001',
        versionNo: '1.0',
        userId: 'logged in user id. nullable',
      ),
    );

 /// provides ResponseModel in return which contains the response from the pinelabs device.
  setState(() {
    _responseMessage = response?.responseMsg ?? '';
  });

setBluetooth

This method can be used to establish bluetooth connection between the PineLab Device & PineLab Charging base.

This API takes the following parameters:

  1. baseSerialNumber: This is the serial number of the PineLab Charging Base.
  2. overrideHeader: This is the header that is to be used for the transaction. This is used to override the header that is configured while initializing the flutter_pinelabs. This can be null only if header was provided during initialization.
// Snippet to implement sendRequest
final response = await _flutterPinelabsPlugin.setBluetooth(
      baseSerialNumber: [BaseSerialNumber]
      overrideHeader: HeaderModel(
        applicationId: 'your application id issued by pinelabs.',
        methodId: '1005',
        versionNo: '1.0',
        userId: 'logged in user id. nullable',
      ),
    );

 /// provides ResponseModel in return which contains the response from the pinelabs device.
  setState(() {
    _responseMessage = response?.responseMsg ?? '';
  });

startScan

This method can be used to fetch the scanned data from scanner connected to the charging base of PineLab device. Bluetooth connection is required between the PineLab device and charging base.

This API takes the following parameters:

  1. baseSerialNumber: This is the serial number of the PineLab Charging Base.
  2. overrideHeader: This is the header that is to be used for the transaction. This is used to override the header that is configured while initializing the flutter_pinelabs. This can be null only if header was provided during initialization.
// Snippet to implement sendRequest
final response = await _flutterPinelabsPlugin.startScan(
      baseSerialNumber: [BaseSerialNumber]
      overrideHeader: HeaderModel(
        applicationId: 'your application id issued by pinelabs.',
        methodId: '1007',
        versionNo: '1.0',
        userId: 'logged in user id. nullable',
      ),
    );

 /// provides ResponseModel in return which contains the response from the pinelabs device.
  setState(() {
    _responseMessage = response?.scannedData ?? '';
  });

stopScan

This method can be used to reset and stop the scanner service. Bluetooth connection is required between the PineLab device and charging base.

This API takes the following parameters:

  1. baseSerialNumber: This is the serial number of the PineLab Charging Base.
  2. overrideHeader: This is the header that is to be used for the transaction. This is used to override the header that is configured while initializing the flutter_pinelabs. This can be null only if header was provided during initialization.
// Snippet to implement sendRequest
final response = await _flutterPinelabsPlugin.stopScan(
      baseSerialNumber: [BaseSerialNumber]
      overrideHeader: HeaderModel(
        applicationId: 'your application id issued by pinelabs.',
        methodId: '1012',
        versionNo: '1.0',
        userId: 'logged in user id. nullable',
      ),
    );

 /// provides ResponseModel in return which contains the response from the pinelabs device.
  setState(() {
    _responseMessage = response?.responseMsg ?? '';
  });

sendRequest

sendRequest method is used to send json request to the device directly without any manipulation. You can use this method to pass the json and receive json response from the device.

// Snippet to implement sendRequest

  final response = await _flutterPinelabsPlugin.sendRequest(
      requestJson: '{"Header":{"ApplicationId":"your application id issued by pinelabs.","UserId":"1","MethodId":"1001","VersionNo":"1.0"},"Detail":{"TransactionType":"4001","BillingRefNo":"12345","PaymentAmount":"32.52","MobileNumberForEChargeSlip":"9876543210"}}');

  /// provides ResponseModel in return which contains the response from the pinelabs device.
  setState(() {
    _responseMessage = response["Response"]["ResponseMsg"];
  });

printData

This method will be called when billing App wants to print paper-receipt on Plutus Smart Device.

This method takes 2 parameters:

  1. overrideHeader: this parameter is used to override the header provided when FlutterPinelabs was initialized. If it is null, header from initialisation is used.
  2. printRequest: Print request contains all the data that needs to be printed. (currently only printing text is tested)

Additional Notes:

Failure Response from the device when timedout:

{
  "Header": {
    "ApplicationId": "something",
    "MethodId": "1001",
    "UserId": "1",
    "VersionNo": "1.0"
  },
  "Response": {
    "AppVersion": "638",
    "ParameterJson": "parameter",
    "ResponseCode": 7,
    "ResponseMsg": "Something went wrong!"
  }
}

Failer Response from the device when back pressed:

{
  "Header": {
    "ApplicationId": "something",
    "MethodId": "1001",
    "UserId": "1",
    "VersionNo": "1.0"
  },
  "Response": {
    "AppVersion": "638",
    "ParameterJson": "parameter",
    "ResponseCode": 7,
    "ResponseMsg": "Card reading Error"
  }
}

Success Reponse from the device:

{
  "Detail": {
    "AcquirerName": "ICICI BANK",
    "AcquiringBankCode": "02",
    "ApprovalCode": "00",
    "AuthAmoutPaise": "9999000",
    "BatchNumber": 4,
    "BillingRefNo": "TXN12345678",
    "CardEntryMode": "CARD_CHIP",
    "CardNumber": "************abcd",
    "CardType": "VISA",
    "CardholderName": "Some Person",
    "ExpiryDate": "XXXX",
    "HostResponse": "APPROVED",
    "InvoiceNumber": 1,
    "LoyaltyPointsAwarded": 0,
    "MerchantAddress": "JANAKPURI",
    "MerchantCity": "NEW DELHI    DEL       ",
    "MerchantId": "               ",
    "MerchantName": "LOVE COMMUNICATION",
    "PlutusTransactionLogID": "4295187240",
    "PlutusVersion": "Plutus v2.12 MT ICICI BANK",
    "PosEntryMode": 2,
    "PrintCardholderName": 1,
    "Remark": "PROCESSED",
    "RetrievalReferenceNumber": "000000000020",
    "TerminalId": "30365626",
    "TransactionDate": "06132022",
    "TransactionTime": "150726",
    "TransactionType": 4001
  },
  "Header": {
    "ApplicationId": "something",
    "MethodId": "1001",
    "UserId": "1",
    "VersionNo": "1.0"
  },
  "Response": {
    "AppVersion": "638",
    "ParameterJson": "parameter",
    "ResponseCode": 0,
    "ResponseMsg": "APPROVED"
  }
}

Future Scope:

Implement remaining methods such as:
x Print Data
Settlement
Get Terminal Info
x Connect Bluetooth
x Disconnect Bluetooth
x Scan QR Code/Barcode
Single/Multi Scan QR/Barcode Code from Camera