Link Transactions to Receipts

Introduction

We provide the ability to submit a bank account transaction identifier when capturing a paper receipt.

This provides facilitates creating link between a particular receipt and a bank transaction.

This is helpful if an integrating app requires the ability to display a receipt associated with a particular bank account transaction, or display all receipts associated with a particular bank account.

Attaching a Transaction Id to the Receipt Capture Flow

  1. Initialize Transaction (SBLTransaction in Objective-C) with externalAccountTransactionID.
  2. Initialize CaptureFlowCoordinator with the host UIViewController that will be presenting the transaction linking flow.
  3. Set delegate of above created instance to the host UIViewController.
  4. Start transaction linking flow by passing Transaction object created in Step 1 using start(transaction:) method on instance of CaptureFlowCoordinator created in Step 2
  5. Retain instance of coordinator.
  6. Optionally (recommended) register a transaction observer with SBDataEvent , so you can provide custom handling of various receipt uploading states for a provided Transaction.

Note:

  • The Transaction object represents a Sensibill receipt uploading transaction.
  • The bank account transaction identifier (called externalAccountTransactionID below) is a free-form string that supports various transaction identifiers. It can be provided by the integrator via the privateMetaData.accountTransactionID property of the Transaction object.
  • It’s important to differentiate the bank account transaction identifier from the Sensibill transaction identifier (a read-only property called remoteID, not mentioned in example below).

Example

import Sensibill

class ViewController: UIViewController {

    // MARK: - Private Properties

    private var captureFlowCoordinator: CaptureFlowCoordinator?

    // MARK: - Private Methods

    private func presentReceiptCapture(externalAccountTransactionID: String) {

        // Step 1
        let sensibillTransaction = Transaction(externalAccountTransactionID: externalAccountTransactionID)

        // Step 2
        let coordinator = CaptureFlowCoordinator(host: self)

        // Step 3
        coordinator.delegate = self

       // Step 4
       coordinator.start(transaction: sensibillTransaction)

       // Step 5
       self.captureFlowCoordinator = coordinator

       // Optional Step 6: uncomment the following line to enable (function is shown in section below)
       // registerTransactionObserver(externalAccountTransactionID: externalAccountTransactionID)

    }
}


// MARK: - CaptureFlowCoordinatorDelegate

extension ViewController: CaptureFlowCoordinatorDelegate {

    public func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, transactions: [Transaction]) {
        self.captureFlowCoordinator = nil
    }

    public func coordinatorDidCancelCapture(_ coordinator: CaptureFlowCoordinator) {
        self.captureFlowCoordinator = nil
    }
}

When launching the Receipt Capture Flow , a transaction id can be provided. If a transaction id is provided, the transaction id will be attached as metadata to any receipt object that is created as a result of the capture flow.

For reference, the following snippets would be inserted in place of the code in step 3 of the Use Receipt Capture guide .

Kotlin

val myTransaction: MyTransactionModel // Your transaction model

captureFlow.launchCaptureFlow(
    captureFlowListener,
    externalAccountTransactionId = myTransaction.id
)

Java

final MyTransactionModel myTransaction;  // Your transaction model

captureFlow.launchCaptureFlow(
    captureFlowListener,
    CaptureFlowCoordinator.Companion.getDEFAULT_CONFIG()
    externalAccountTransactionId = myTransaction.getId()
);

Reference The Receipt Capture Flow
CaptureFlowCoordinator

Web SDK does not support Transaction Linking

Monitoring uploads

The following example demonstrates receiving and handling status updates related to uploading a Sensibill transaction with a provided externalAccountTransactionID. This function can be called right before presenting capture (as shown above in presentReceiptCapture example), or earlier.

func registerTransactionObserver(externalAccountTransactionID: String) {

    SBDataEvent.sharedManager().addTransactionObserver(self) { (type, transaction) in

        guard type == .statusUpdate else {
            // Different notification type is received (not in scope for this example)
            return
        }

        guard let transaction = transaction else {
            // Failed to unwrap transaction object (normally shouldn't happen)
            return
        }

        guard transaction.privateMetaData?.externalAccountTransactionID == externalAccountTransactionID else {
            // Notification is for a different transaction, and can be ignored
            return
        }

        switch transaction.status {
        case .uploading:
            // Receipt image was locally validated and is uploading to the server
            break
        case .processing:
            // Receipt image was accepted by the Sensibill API server for processing
            break
        case .failed:
            // Receipt processing failed
            // Note: this state is set for failure on any stage
            // Optional step: check transaction.error for possible cause
            break
        case .completed:
            // Receipt was processed successfully
            // It must now have transaction.receiptID
            guard let receiptID = transaction.receiptID else {
                // Error: receipt ID is not set for complete transaction
                return
            }
            break
        case .unknown:
            // Initial transaction status
            // (no notification is sent for this status)
            break
        @unknown default:
            // SDK introduced a new status, please review Migration Guide.
            break
        }
    }
}

The following example demonstrates how to unlink external account transaction associated with specific receipt by submitting edit receipt request to Sensibill API using associated receiptID.

func unlinkAccountTransaction(forReceiptID receiptID: String) {

  let editRequestMethod = "PUT"
  let ediReceiptRequestEndPoint = URLConstant.editReceiptRequestEndPoint(receiptID: receiptID)
  let editReceiptRequestParameters = ["edit": ["accountTransactionData": ["id": ""]]]

  let request = Request(authenticationType: .token,
                        method: editRequestMethod,
                        endPoint: ediReceiptRequestEndPoint,
                        parameters: editReceiptRequestParameters,
                        data: nil)

  request.start { [weak self] (response, error, code) in

    if let _ = response, code == 200 {
      // Unlink successful.
      return
    }

    // Unlink failed.
  }

}