Class: Payment::Gateways::Echeck
- Inherits:
-
BasePaymentGateway
- Object
- BasePaymentGateway
- Payment::Gateways::Echeck
- Defined in:
- app/services/payment/gateways/echeck.rb
Overview
Manual eCheck gateway. Heatwave runs eChecks through Forte
out-of-band, so this strategy records audit transactions and flips
Payment state without contacting an API. Each public action also
notifies AR via #notify_forte_pending so they can process the actual
transfer — guarded because FinancialsMailer#forte_payment_pending was
removed and may not be defined.
Defined Under Namespace
Classes: Result
Instance Method Summary collapse
-
#authorize ⇒ Payment::Gateways::Echeck::Result
Stamp the payment with a masked account number, write a fake
authorizationtransaction, and notify AR. -
#capture(capture_amount, _options = {}) ⇒ Payment::Gateways::Echeck::Result
Append a manual
capturetransaction and flip the Payment into captured. -
#create_receipt(invoice, amount, balance) ⇒ Payment::Gateways::Echeck::Result
Create a Receipt against
invoiceforamount. -
#initialize(payment, _delivery = nil) ⇒ Echeck
constructor
A new instance of Echeck.
-
#purchase(receipt, _options = {}) ⇒ Payment::Gateways::Echeck::Result
One-shot "process this eCheck now" entry point used by ReceiptsController#create when the operator submits the receipt form with "Process Payment" checked.
-
#refund(refund_amount, credit_memo) ⇒ Payment::Gateways::Echeck::Result
Issue a manual eCheck refund and create the matching Receipt against
credit_memo. -
#void(_report_fraud = false) ⇒ Payment::Gateways::Echeck::Result
Mark an authorized eCheck voided.
Constructor Details
#initialize(payment, _delivery = nil) ⇒ Echeck
Returns a new instance of Echeck.
14 15 16 |
# File 'app/services/payment/gateways/echeck.rb', line 14 def initialize(payment, _delivery = nil) @payment = payment end |
Instance Method Details
#authorize ⇒ Payment::Gateways::Echeck::Result
Stamp the payment with a masked account number, write a fake
authorization transaction, and notify AR. Forte processing
happens externally.
23 24 25 26 27 |
# File 'app/services/payment/gateways/echeck.rb', line 23 def Result.new(success: true, message: 'eCheck payment authorized (manual processing)') end |
#capture(capture_amount, _options = {}) ⇒ Payment::Gateways::Echeck::Result
Append a manual capture transaction and flip the Payment into
captured. Funds movement happens at Forte separately.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/services/payment/gateways/echeck.rb', line 64 def capture(capture_amount, = {}) tx = OrderTransaction.new( action: 'capture', amount: (capture_amount * 100).to_i, success: true, reference: @payment. || @payment.reference, message: 'Manual eCheck capture', params: { manual: true }, test: !Rails.env.production? ) @payment.transactions.push(tx) @payment.payment_captured! Rails.logger.info("#{Time.current}: eCheck capture of Payment ID #{@payment.id} Amount #{capture_amount}") Result.new(success: true, message: 'ok') end |
#create_receipt(invoice, amount, balance) ⇒ Payment::Gateways::Echeck::Result
Create a Receipt against invoice for amount. When the eCheck
captured more than the invoice balance, also notifies admin so AR
knows to issue a manual refund.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'app/services/payment/gateways/echeck.rb', line 169 def create_receipt(invoice, amount, balance) new_receipt = @payment.receipts.new( company: invoice.company, customer: invoice.customer, category: 'Echeck', amount: amount, reference: @payment.reference, currency: invoice.currency, payment: @payment, bank_account: invoice.company.cc_bank_account, gl_date: Date.current, receipt_date: Date.current ) new_receipt.receipt_details << ReceiptDetail.new( category: 'Invoice', invoice: invoice, amount: amount, gl_date: Date.current ) begin new_receipt.save! Rails.logger.info("#{Time.current}: Created new receipt id: #{new_receipt.id}") if @payment.amount > balance Mailer.admin_notification( "Echeck amount already captured greater than balance on invoice id: #{invoice.id}, ref: #{invoice.reference_number}", "Amount already captured for eCheck payment id: #{@payment.id} was greater than order balance. eCheck amount: #{@payment.amount}, Invoice balance: #{balance}. Inform accounting who should process a refund." ).deliver end success = true rescue StandardError => e report_exception e, payment_id: @payment.id, message: "Unable to create new receipt for echeck" success = false end Result.new(success: success, receipt: new_receipt) end |
#purchase(receipt, _options = {}) ⇒ Payment::Gateways::Echeck::Result
One-shot "process this eCheck now" entry point used by
ReceiptsController#create when the operator submits the receipt
form with "Process Payment" checked. Forte moves the funds
out-of-band, so this authorizes the eCheck (masked reference, manual
authorization transaction, pending -> authorized), attaches and
persists the operator-entered Receipt, and returns the same
success / receipt contract that
CreditCard#purchase hands back to the controller.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'app/services/payment/gateways/echeck.rb', line 41 def purchase(receipt, = {}) receipt.reference = @payment.reference receipt.card_type = @payment.card_type receipt.payment = @payment begin receipt.save! Rails.logger.info("#{Time.current}: eCheck purchase of Payment ID #{@payment.id} Amount #{@payment.amount} - created receipt id #{receipt.id}") Result.new(success: true, message: 'ok', receipt: receipt) rescue StandardError => e report_exception e, payment_id: @payment.id, message: 'eCheck authorized but receipt failed to save' Result.new(success: false, message: 'eCheck authorized but receipt failed to save', receipt: receipt) end end |
#refund(refund_amount, credit_memo) ⇒ Payment::Gateways::Echeck::Result
Issue a manual eCheck refund and create the matching Receipt
against credit_memo. Errors creating the receipt are reported to
AppSignal but the refund transaction itself still records.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'app/services/payment/gateways/echeck.rb', line 115 def refund(refund_amount, credit_memo) tx = OrderTransaction.new( action: 'refund', amount: (refund_amount * 100).to_i, success: true, reference: @payment. || @payment.reference, message: 'Manual eCheck refund', params: { manual: true }, test: !Rails.env.production? ) @payment.transactions.push(tx) @payment.payment_refunded! Rails.logger.info("#{Time.current}: eCheck Refund of Payment ID #{@payment.id} Amount #{refund_amount}") new_receipt = Receipt.new( company: credit_memo.company, customer: credit_memo.customer, category: 'Echeck', amount: -refund_amount, reference: @payment.reference, card_type: @payment.card_type, currency: @payment.currency, payment: @payment, bank_account: @payment.invoice.company.cc_bank_account, gl_date: Date.current, receipt_date: Date.current ) new_receipt.receipt_details << ReceiptDetail.new( category: 'Credit Memo', credit_memo: credit_memo, amount: -refund_amount, gl_date: Date.current ) receipt_ok = false begin new_receipt.save! receipt_ok = true Rails.logger.info("#{Time.current}: Created new receipt id: #{new_receipt.id}") rescue StandardError => e report_exception e, payment_id: @payment.id, message: "Payment refunded but no receipt" end notify_forte_pending Result.new(success: receipt_ok, receipt: new_receipt) end |
#void(_report_fraud = false) ⇒ Payment::Gateways::Echeck::Result
Mark an authorized eCheck voided. Records a manual void
transaction and re-notifies AR so they can stop the Forte run.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'app/services/payment/gateways/echeck.rb', line 87 def void(_report_fraud = false) return Result.new(success: false) unless @payment. tx = OrderTransaction.new( action: 'void', success: true, reference: @payment. || @payment.reference, message: 'Manual eCheck void', params: { manual: true }, test: !Rails.env.production? ) @payment.transactions.push(tx) @payment.payment_voided! Rails.logger.info("#{Time.current}: eCheck Void of Payment ID #{@payment.id}") notify_forte_pending Result.new(success: true, message: 'voided') end |