From aa5566208b65e025c5af5a822dbc236e77391524 Mon Sep 17 00:00:00 2001 From: itsdeka Date: Tue, 14 Dec 2021 23:11:56 +0100 Subject: [PATCH 1/2] Added bitfinex-pay merchants endpoints --- CHANGELOG | 3 + bfxapi/rest/bfx_rest.py | 130 ++++++++++++++++++++++++++++++++++++++++ bfxapi/version.py | 2 +- setup.py | 2 +- 4 files changed, 135 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 748b42a..d983ec4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +1.3.2 +-) Implemented Merchants endpoints (REST) + 1.3.1 -) Handle exception of asyncio.get_event_loop() | Related to v1.2.8 diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 81fff4a..430d72d 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -1109,3 +1109,133 @@ class BfxRest: payload['symbol'] = symbol payload['collateral'] = collateral return await self.post(endpoint, data=payload) + + ################################################## + # Merchants # + ################################################## + + async def submit_invoice(self, amount, currency, pay_currencies, order_id, webhook, redirect_url, customer_info_nationality, + customer_info_resid_country, customer_info_resid_city, customer_info_resid_zip_code, + customer_info_resid_street, customer_info_full_name, customer_info_email, + customer_info_resid_state=None, customer_info_resid_building_no=None, duration=None): + """ + Submit an invoice for payment + + # Attributes + @param amount str: Invoice amount in currency (From 0.1 USD to 1000 USD) + @param currency str: Invoice currency, currently supported: USD + @param pay_currencies list of str: Currencies in which invoice accepts the payments, supported values are BTC, ETH, UST-ETH, UST-TRX, UST-LBT, LNX, LBT + @param order_id str: Reference order identifier in merchant's platform + @param webhook str: The endpoint that will be called once the payment is completed/expired + @param redirect_url str: Merchant redirect URL, this one is used in UI to redirect customer to merchant's site once the payment is completed/expired + @param customer_info_nationality str: Customer's nationality, alpha2 code or full country name (alpha2 preffered) + @param customer_info_resid_country str: Customer's residential country, alpha2 code or full country name (alpha2 preffered) + @param customer_info_resid_city str: Customer's residential city/town + @param customer_info_resid_zip_code str: Customer's residential zip code/postal code + @param customer_info_resid_street str: Customer's residential street address + @param customer_info_full_name str: Customer's full name + @param customer_info_email str: Customer's email address + @param customer_info_resid_state str: Optional, customer's residential state/province + @param customer_info_resid_building_no str: Optional, customer's residential building number/name + @param duration int: Optional, invoice expire time in seconds, minimal duration is 5 mins (300) and maximal duration is 24 hours (86400). Default value is 15 minutes + """ + endpoint = '/auth/w/ext/pay/invoice/create' + payload = { + 'amount': amount, + 'currency': currency, + 'payCurrencies': pay_currencies, + 'orderId': order_id, + 'webhook': webhook, + 'redirectUrl': redirect_url, + 'customerInfo': { + 'nationality': customer_info_nationality, + 'residCountry': customer_info_resid_country, + 'residCity': customer_info_resid_city, + 'residZipCode': customer_info_resid_zip_code, + 'residStreet': customer_info_resid_street, + 'fullName': customer_info_full_name, + 'email': customer_info_email + }, + 'duration': duration + } + + if customer_info_resid_state: + payload['customerInfo']['residState'] = customer_info_resid_state + + if customer_info_resid_building_no: + payload['customerInfo']['residBuildingNo'] = customer_info_resid_building_no + + return await self.post(endpoint, data=payload) + + async def get_invoices(self, id=None, start=None, end=None, limit=10): + """ + List submitted invoices + + # Attributes + @param id str: Unique invoice identifier + @param start int: Millisecond start time + @param end int: Millisecond end time + @param limit int: Millisecond start time + """ + endpoint = '/auth/w/ext/pay/invoices' + payload = {} + + if id: + payload['id'] = id + + if start: + payload['start'] = start + + if end: + payload['end'] = end + + if limit: + payload['limit'] = limit + + return await self.post(endpoint, data=payload) + + async def complete_invoice(self, id, pay_ccy, deposit_id=None, ledger_id=None): + """ + Manually complete an invoice + + # Attributes + @param id str: Unique invoice identifier + @param pay_ccy str: Paid invoice currency, should be one of values under payCurrencies field on invoice + @param deposit_id int: Movement/Deposit Id linked to invoice as payment + @param ledger_id int: Ledger entry Id linked to invoice as payment, use either depositId or ledgerId + """ + endpoint = '/auth/w/ext/pay/invoice/complete' + payload = { + 'id': id, + 'payCcy': pay_ccy + } + + if deposit_id: + payload['depositId'] = deposit_id + + if ledger_id: + payload['ledgerId'] = ledger_id + + return await self.post(endpoint, data=payload) + + async def get_unlinked_deposits(self, ccy, start=None, end=None): + """ + Retrieve deposits that possibly could be linked to bitfinex pay invoices + + # Attributes + @param ccy str: Pay currency to search deposits for, supported values are: BTC, ETH, UST-ETH, UST-TRX, UST-LBT, LNX, LBT + @param start int: Millisecond start time + @param end int: Millisecond end time + """ + endpoint = '/auth/w/ext/pay/deposits/unlinked' + payload = { + 'ccy': ccy + } + + if start: + payload['start'] = start + + if end: + payload['end'] = end + + return await self.post(endpoint, data=payload) diff --git a/bfxapi/version.py b/bfxapi/version.py index 880ed5d..51534a7 100644 --- a/bfxapi/version.py +++ b/bfxapi/version.py @@ -2,4 +2,4 @@ This module contains the current version of the bfxapi lib """ -__version__ = '1.3.1' +__version__ = '1.3.2' diff --git a/setup.py b/setup.py index 2098d8e..3444a25 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ from os import path here = path.abspath(path.dirname(__file__)) setup( name='bitfinex-api-py', - version='1.3.1', + version='1.3.2', description='Official Bitfinex Python API', long_description='A Python reference implementation of the Bitfinex API for both REST and websocket interaction', long_description_content_type='text/markdown', From 35ee037eccc94c522960627cc947421240a790d9 Mon Sep 17 00:00:00 2001 From: itsdeka Date: Wed, 15 Dec 2021 13:47:35 +0100 Subject: [PATCH 2/2] added merchant example | fixed endpoints --- bfxapi/examples/rest/merchant.py | 33 ++++++++++++++++++++++++++++++++ bfxapi/rest/bfx_rest.py | 8 ++++---- 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 bfxapi/examples/rest/merchant.py diff --git a/bfxapi/examples/rest/merchant.py b/bfxapi/examples/rest/merchant.py new file mode 100644 index 0000000..91521fa --- /dev/null +++ b/bfxapi/examples/rest/merchant.py @@ -0,0 +1,33 @@ +import os +import sys +import asyncio +sys.path.append('../../../') +from bfxapi import Client + +API_KEY=os.getenv("BFX_KEY") +API_SECRET=os.getenv("BFX_SECRET") + +bfx = Client( + API_KEY=API_KEY, + API_SECRET=API_SECRET, + logLevel='DEBUG' +) + +async def run(): + await bfx.rest.submit_invoice(amount='2.0', currency='USD', pay_currencies=['BTC', 'ETH'], order_id='order123', webhook='https://example.com/api/v3/order/order123', + redirect_url='https://example.com/api/v3/order/order123', customer_info_nationality='DE', + customer_info_resid_country='GB', customer_info_resid_city='London', customer_info_resid_zip_code='WC2H 7NA', + customer_info_resid_street='5-6 Leicester Square', customer_info_resid_building_no='23 A', + customer_info_full_name='John Doe', customer_info_email='john@example.com', duration=86339) + + invoices = await bfx.rest.get_invoices() + print(invoices) + + # await bfx.rest.complete_invoice(id=invoices[0]['id'], pay_ccy='BTC', deposit_id=1357996) + + unlinked_deposits = await bfx.rest.get_unlinked_deposits(ccy='BTC') + print(unlinked_deposits) + + +t = asyncio.ensure_future(run()) +asyncio.get_event_loop().run_until_complete(t) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 430d72d..a2a104e 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -1139,7 +1139,7 @@ class BfxRest: @param customer_info_resid_building_no str: Optional, customer's residential building number/name @param duration int: Optional, invoice expire time in seconds, minimal duration is 5 mins (300) and maximal duration is 24 hours (86400). Default value is 15 minutes """ - endpoint = '/auth/w/ext/pay/invoice/create' + endpoint = 'auth/w/ext/pay/invoice/create' payload = { 'amount': amount, 'currency': currency, @@ -1177,7 +1177,7 @@ class BfxRest: @param end int: Millisecond end time @param limit int: Millisecond start time """ - endpoint = '/auth/w/ext/pay/invoices' + endpoint = 'auth/r/ext/pay/invoices' payload = {} if id: @@ -1204,7 +1204,7 @@ class BfxRest: @param deposit_id int: Movement/Deposit Id linked to invoice as payment @param ledger_id int: Ledger entry Id linked to invoice as payment, use either depositId or ledgerId """ - endpoint = '/auth/w/ext/pay/invoice/complete' + endpoint = 'auth/w/ext/pay/invoice/complete' payload = { 'id': id, 'payCcy': pay_ccy @@ -1227,7 +1227,7 @@ class BfxRest: @param start int: Millisecond start time @param end int: Millisecond end time """ - endpoint = '/auth/w/ext/pay/deposits/unlinked' + endpoint = 'auth/r/ext/pay/deposits/unlinked' payload = { 'ccy': ccy }