From 213ff71c8a1e2de70be43ea00fcfff8bdc1e41ef Mon Sep 17 00:00:00 2001 From: Szymon Wlodarski Date: Fri, 24 Jan 2025 10:51:15 +0100 Subject: [PATCH] SP-1155: use resource token in webhook resend requests --- pyproject.toml | 2 +- src/bitpay/client.py | 12 ++++++++---- src/bitpay/clients/invoice_client.py | 7 +++++-- src/bitpay/clients/refund_client.py | 5 +++-- src/bitpay/config.py | 2 +- tests/unit/test_client.py | 10 ++++++---- 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 64b46ac..b3dc270 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "bitpay" -version = "7.0.0" +version = "7.0.1" authors = [ { name="Antonio Buedo", email="sales-engineering@bitpay.com" }, ] diff --git a/src/bitpay/client.py b/src/bitpay/client.py index a523439..71297c6 100644 --- a/src/bitpay/client.py +++ b/src/bitpay/client.py @@ -353,18 +353,21 @@ def pay_invoice(self, invoice_id: str, status: str = "complete") -> Invoice: client = self.create_invoice_client() return client.pay(invoice_id, status) - def request_invoice_notifications(self, invoice_id: str) -> bool: + def request_invoice_notifications( + self, invoice_id: str, invoice_token: str + ) -> bool: """ Request a BitPay Invoice Webhook. :param str invoice_id: A BitPay invoice ID. + :param str invoice_token: The resource token for the invoice_id. This token can be retrieved from the Bitpay's invoice object. :return: True if the webhook was successfully requested, false otherwise. :rtype: bool :raises BitPayException :raises InvoiceNotificationException """ client = self.create_invoice_client() - return client.request_invoice_notifications(invoice_id) + return client.request_invoice_notifications(invoice_id, invoice_token) def create_refund( self, @@ -501,18 +504,19 @@ def cancel_refund_by_guid(self, guid: str) -> Refund: client = self.create_refund_client() return client.cancel_by_guid(guid) - def request_refund_notification(self, refund_id: str) -> bool: + def request_refund_notification(self, refund_id: str, refund_token: str) -> bool: """ Send a refund notification. :param str refund_id: BitPay refund ID to notify. + :param str refund_token: The resource token for the refund_id. This token can be retrieved from the Bitpay's refund object. :return: True if the webhook was successfully requested, false otherwise. :rtype: bool :raises BitPayException :raises RefundNotificationException """ client = self.create_refund_client() - return client.request_notification(refund_id) + return client.request_notification(refund_id, refund_token) def get_supported_wallets(self) -> List[Wallet]: """ diff --git a/src/bitpay/clients/invoice_client.py b/src/bitpay/clients/invoice_client.py index 4790e15..c92ec98 100644 --- a/src/bitpay/clients/invoice_client.py +++ b/src/bitpay/clients/invoice_client.py @@ -335,17 +335,20 @@ def pay(self, invoice_id: str, status: str) -> Invoice: return invoice - def request_invoice_notifications(self, invoice_id: str) -> bool: + def request_invoice_notifications( + self, invoice_id: str, invoice_token: str + ) -> bool: """ Request a BitPay Invoice Webhook. :param str invoice_id: A BitPay invoice ID. + :param str invoice_token: The resource token for the invoice_id. This token can be retrieved from the Bitpay's invoice object. :return: True if the webhook was successfully requested, false otherwise. :rtype: bool :raises BitPayApiException :raises BitPayGenericException """ - params = {"token": self.__token_container.get_access_token(Facade.MERCHANT)} + params = {"token": invoice_token} response = self.__bitpay_client.post( "invoices/%s" % invoice_id + "/notifications", params ) diff --git a/src/bitpay/clients/refund_client.py b/src/bitpay/clients/refund_client.py index 4badac0..6e51e45 100644 --- a/src/bitpay/clients/refund_client.py +++ b/src/bitpay/clients/refund_client.py @@ -238,17 +238,18 @@ def cancel_by_guid(self, guid: str) -> Refund: "Refund", str(exe) ) - def request_notification(self, refund_id: str) -> bool: + def request_notification(self, refund_id: str, refund_token: str) -> bool: """ Send a refund notification. :param str refund_id: BitPay refund ID to notify. + :param str refund_token: The resource token for the refund_id. This token can be retrieved from the Bitpay's refund object. :return: True if the webhook was successfully requested, false otherwise. :rtype: bool :raises BitPayApiException :raises BitPayGenericException """ - params = {"token": self.__token_container.get_access_token(Facade.MERCHANT)} + params = {"token": refund_token} response = self.__bitpay_client.post( "refunds/%s" % refund_id + "/notifications", params, True ) diff --git a/src/bitpay/config.py b/src/bitpay/config.py index 18f7363..511f1ab 100644 --- a/src/bitpay/config.py +++ b/src/bitpay/config.py @@ -5,6 +5,6 @@ class Config(Enum): TEST_URL = "https://test.bitpay.com/" PROD_URL = "https://bitpay.com/" BITPAY_API_VERSION = "2.0.0" - BITPAY_PLUGIN_INFO = "BitPay_Python_Client_v7.0.0" + BITPAY_PLUGIN_INFO = "BitPay_Python_Client_v7.0.1" BITPAY_API_FRAME = "std" BITPAY_API_FRAME_VERSION = "1.0.0" diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index aa1c833..aaeb437 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -26,6 +26,7 @@ payout_token_value = "somePayoutToken" pos_token_value = "somePosToken" invoice_id = "UZjwcYkWAKfTMn9J1yyfs4" +invoice_token = "someInvoiceToken" def get_bitpay_client(mocker): @@ -542,14 +543,14 @@ def test_request_invoice_notifications(mocker): bitpay_client = get_bitpay_client(mocker) response = Mock() response.json.return_value = {"data": "success"} - params = {"token": merchant_token_value} + params = {"token": invoice_token} bitpay_client.post.side_effect = mock_response( response, "invoices/" + invoice_id + "/notifications", params, True ) client = init_client(mocker, bitpay_client) # act - result = client.request_invoice_notifications(invoice_id) + result = client.request_invoice_notifications(invoice_id, invoice_token) # assert assert result is True @@ -731,17 +732,18 @@ def update_refund_by_guid(mocker): def test_send_refund_notification(mocker): # arrange refund_id = "1234" + refund_token = "someRefundToken" bitpay_client = get_bitpay_client(mocker) response = Mock() response.json.return_value = {"status": "success"} - params = {"token": merchant_token_value} + params = {"token": refund_token} bitpay_client.post.side_effect = mock_response( response, "refunds/" + refund_id + "/notifications", params, True ) client = init_client(mocker, bitpay_client) # act - result = client.request_refund_notification(refund_id) + result = client.request_refund_notification(refund_id, refund_token) # assert assert result is True