def _setup_fake_merchant(): try: merchant_name = os.getenv("FAKE_MERCHANT_NAME", "LRM Merchant") if Merchant.query.filter_by(name=merchant_name).first(): return db_session.add( Merchant( name=merchant_name, settlement_information=os.getenv( "FAKE_MERCHANT_SETTLEMENT_INFO", "Fake Bank, Account #808-909"), settlement_currency="USD", api_key=os.getenv("FAKE_MERCHANT_API_KEY", "abcdefghijklmnop"), )) db_session.commit() except IntegrityError: pass
def payout(merchant: Merchant, payment: Payment): if not payment_can_payout(payment): raise InvalidPaymentStatus("invalid_status") settlement_information = merchant.settlement_information settlement_currency = merchant.settlement_currency if settlement_information in ( None, "", ) or settlement_currency in (None, ""): raise InvalidPaymentStatus("invalid_merchant_information") client_payments = [ transaction for transaction in payment.chain_transactions if transaction.is_refund is False ] if 1 != len(client_payments): raise InvalidPaymentStatus("invalid_transaction") client_payment = client_payments[0] # 1. Get liquidity quote liquidity_provider = FiatLiquidityWrapper(client_payment.currency) payment.set_status(PaymentStatus.payout_processing) db_session.commit() # 2. Send requested amount payout_target, quote = liquidity_provider.pay_out( settlement_currency, client_payment.amount, merchant.settlement_information, ) # 3. Pay according to quote to payout_target tx_id, _ = OnchainWallet().send_transaction( DiemCurrency(client_payment.currency), client_payment.amount, liquidity_provider.vasp_address(), payout_target.bytes[:utils.SUB_ADDRESS_LEN].hex(), ) payment.set_status(PaymentStatus.payout_completed) db_session.commit() return payout_target, quote, tx_id, settlement_information
def db(): clear_db() # Add Merchant and Payment for testing merchant = Merchant( api_key=TOKEN_1, settlement_information=MERCHANT_MOCK_ADDR, settlement_currency=MERCHAND_CURRENCY, ) db_session.add(merchant) db_session.commit() payment = Payment( id=PAYMENT_ID, merchant_id=merchant.id, merchant_reference_id=CREATED_ORDER_ID, requested_amount=1, requested_currency="USD", subaddress=PAYMENT_SUBADDR, expiry_date=datetime.utcnow() + timedelta(minutes=10), ) payment.payment_options.extend([ PaymentOption( payment_id=payment.id, amount=PAYMENT_AMOUNT, currency=PAYMENT_CURRENCY, ), PaymentOption( payment_id=payment.id, amount=PAYMENT_AMOUNT_2, currency=PAYMENT_CURRENCY, ), ]) cleared_payment = Payment( id=CLEARED_PAYMENT_ID, merchant_reference_id=CLEARED_ORDER_ID, merchant_id=merchant.id, requested_amount=10, requested_currency="USD", status=PaymentStatus.cleared, subaddress="f3704755d1100cd2", expiry_date=datetime.utcnow() - timedelta(minutes=10), ) cleared_payment.payment_options.append( PaymentOption( payment_id=cleared_payment.id, amount=cleared_payment.requested_amount, currency=cleared_payment.requested_currency, )) cleared_payment.add_chain_transaction( sender_address=identifier.encode_account(SENDER_MOCK_ADDR, SENDER_MOCK_SUBADDR, CHAIN_HRP), amount=10, currency=DEFAULT_DIEM_CURRENCY, tx_id=CLEARED_TX_ID, ) rejected_payment = Payment( id=REJECTED_PAYMENT_ID, merchant_id=merchant.id, merchant_reference_id=REJECTED_ORDER_ID, status=PaymentStatus.rejected, requested_amount=100, requested_currency="USD", expiry_date=datetime.utcnow(), subaddress=REJECTED_PAYMENT_SUBADDR, ) expired_payment = Payment( id=EXPIRED_PAYMENT_ID, merchant_id=merchant.id, merchant_reference_id=EXPIRED_ORDER_ID, requested_amount=100, requested_currency="USD", subaddress=EXPIRED_PAYMENT_SUBADDR, expiry_date=datetime.utcnow() - timedelta(seconds=1), ) db_session.add(rejected_payment) db_session.add(cleared_payment) db_session.add(expired_payment) db_session.add(payment) db_session.commit() yield db_session
def request_refund(payment): if not payment_can_refund(payment): raise InvalidPaymentStatus("unclearedrefund") payment.refund_requested = True db_session.commit()