module SolidusInter class InterPix < Spree::PaymentMethod preference :client_id, :string preference :client_secret, :string preference :chave_pix, :string preference :conta_corrente, :string preference :crt, :text preference :key, :text def payment_source_class PixPaymentSource end def gateway_class Gateway end def supports?(source) source.is_a?(payment_source_class) end def auto_capture? true end def partial_name "inter_pix" end def create_payment(payment) client = set_api_client inter_payment = client.create_payment( amount: payment.amount, payer_tax_id: payment.source.payer_tax_id, payer_name: payment.source.payer_name, expiration: 600 ) payment.response_code = inter_payment.txid payment.source.assign_attributes( txid: inter_payment.txid, pix_code: inter_payment.copia_e_cola, qr_code_svg: inter_payment.qr_code, status: inter_payment.status, expiration: inter_payment.expiracao, internal_error: inter_payment.internal_error ) payment.log_entries.new(parsed_payment_response_details_with_fallback: failure_response(inter_payment.internal_error)) if inter_payment.internal_error inter_payment end def find_payment(txid) client = set_api_client client.get_payment(txid) end def invalidate_payment(payment) return false unless payment && payment.source.txid inter_payment = find_payment(payment.source.txid) return false if inter_payment.paid? inter_payment.invalidate! payment.log_entries.create!(parsed_payment_response_details_with_fallback: failure_response("Pagamento cancelado")) true end def pay_test_payment payment return false unless payment && payment.source.txid inter_payment = find_payment(payment.source.txid) return false if inter_payment.paid? client = set_api_client client.pay_pix(inter_payment.txid, inter_payment.valor_original) end def purchase(money, source, options = {}) inter_payment = find_payment(source.txid) if inter_payment.paid? source.update(status: "approved", e2e_id: inter_payment.end_to_end_id) successful_response("Pagamento realizado", inter_payment.txid) else failure_response(inter_payment.internal_error || "Ocorreu um erro no pagamento.") end end def should_skip_processing?(source) inter_payment = find_payment(source.txid) !inter_payment.paid? end private def set_api_client account = SolidusInter::Account.find_by(chave_pix: preferences[:chave_pix]) client = ::InterApi::Client.new( client_id: preferences[:client_id], client_secret: preferences[:client_secret], chave_pix: preferences[:chave_pix], conta_corrente: preferences[:conta_corrente], crt: temp_file(preferences[:crt]).path, key: temp_file(preferences[:key]).path, token: account&.token, token_expires_at: account&.expires_at, test_mode: preferences[:test_mode] ) SolidusInter::Account.upsert({token: client.token, expires_at: client.token_expires_at, chave_pix: client.chave_pix, spree_payment_method_id: id}, unique_by: :chave_pix) client end def temp_file content t = Tempfile.new t << content t.close t end def successful_response message, transaction_id ActiveMerchant::Billing::Response.new( true, message, {}, authorization: transaction_id ) end def failure_response message ActiveMerchant::Billing::Response.new( false, message ) end end end