## Transaction Matching Implement a Currency Exchanger to USD, amounts are converted to USD when Request currency is different from Payment currency. ```php use MerchantOP\Services\ExchangerContract; class Exchanger implements ExchangerContract { protected $rates = [ 'EUR' => 1.21, 'GBP' => 1.37, ]; public function __construct() { $this->rates = $this->getFreshRates(); } public function exchangeToUSD($currency, $amount) { return $this->rates[$currency] * $amount; } protected function getFreshRates() { // } } ``` Capture request parameters: ```php use MerchantOP\Models\ProvisionRequest; $request = ProvisionRequest::capture(); ``` Preliminary filter available transactions by card number and transaction date: ```php $transactionDate = $request->authorizationDate ?: $request->settlementDate; $transactions = Transactions::where('card_bin', $request->cardBin) ->where('card_last4', $request->cardLast4) ->where('transaction_timestamp', '>=', $request->authorizationDate->add(DateInterval::createFromDateString('-3 days'))) ->where('transaction_timestamp', '<=', $request->authorizationDate->add(DateInterval::createFromDateString('+3 days'))); ``` Transform raw filtered entities to Payment objects: ```php $payments = $transactions->map(function ($transactions) { $payment = new Payment; $payment->authDate = $transaction->transaction_timestamp; $payment->cardBin = $transaction->card_bin; $payment->cardLast4 = $transaction->card_last4; $payment->total = $transaction->amount; $payment->currency = $transaction->currency; $payment->authDescriptor = $transaction->descriptor; $payment->arn = $transaction->arn; $payment->orderId = $transaction->order_id; return $payment; }); ``` Match Payments to requested parameters: ```php use MerchantOP\OrderPullingManager; $matched = OrderPullingManager::matcher(new Exchanger)->match($payments, $request); ``` Matching steps (the process stops on the step where only a single payment is matched): 1. Exact Match by ARN, Order ID, Gateway ID, if both available in Request and Payment. 2. Match by Card Number, Transaction Date (+- 2 days), Amount (exchanged to USD; on exchange, a difference of 5 USD is accepted) 3. Match by Descriptor (65% similarity; removed numbers, whitespaces) 4. Match by exact payment date Check matched payments: ```php if (!$matched) { abort(404); # Not found } elseif ($matched === true) { abort(300); # Multiple choices } else { $response = new ProvisionResponse; $response->payments[] = $matched; // build response... echo $response->toJson(); } ```