From 894ec7dd71cca1f66238c538f1a468c78907251d Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sat, 1 Mar 2014 16:45:50 -0500 Subject: [PATCH 1/3] Added the test reqs to setup.py. --- setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e75f98c..4d2bd42 100644 --- a/setup.py +++ b/setup.py @@ -25,5 +25,9 @@ 'httplib2>=0.8', 'requests>=1.1.0', 'oauth2client>=1.1' - ] + ], + tests_require=[ + 'sure>=1.2.5', + 'httpretty>=0.8.0', + ], ) From 3f5c0dd87bbbb6413d4f3d79c4fd74d9895e2618 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sat, 1 Mar 2014 18:52:13 -0500 Subject: [PATCH 2/3] Add support for creating payment buttons. --- coinbase/__init__.py | 47 ++++++++++++++++++++++++++++++++++++- coinbase/models/__init__.py | 3 ++- coinbase/models/button.py | 8 +++++++ coinbase/tests.py | 15 +++++++++++- 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 coinbase/models/button.py diff --git a/coinbase/__init__.py b/coinbase/__init__.py index 8530ba5..1a47dd4 100644 --- a/coinbase/__init__.py +++ b/coinbase/__init__.py @@ -45,7 +45,7 @@ #from decimal import Decimal from coinbase.config import COINBASE_ENDPOINT -from coinbase.models import CoinbaseAmount, CoinbaseTransaction, CoinbaseUser, CoinbaseTransfer, CoinbaseError +from coinbase.models import CoinbaseAmount, CoinbaseTransaction, CoinbaseUser, CoinbaseTransfer, CoinbaseError, CoinbasePaymentButton class CoinbaseAccount(object): @@ -465,4 +465,49 @@ def generate_receive_address(self, callback_url=None): return response.json()['address'] + def create_button(self, name, price, price_currency='BTC', + button_type='buy_now', callback_url=None, + **kwargs): + """ + Create a new payment button, page, or iframe. + + Some required parameters are documented, but the rest are supported + as keyword-arguments. + + See https://coinbase.com/api/doc/1.0/buttons/create.html for details. + :param name: The name of the item to be purchased, donated for, or + subscribed. + :param price: The price, in whatever currency specified. Preferably a + string or Decimal. + :param price_currency: The ISO currency in which the price is listed. + Eg, BTC or USD. + :param button_type: Choices are 'buy_now', 'donation', and + 'subscription' + :param callback_url: The URL to receive instant payment notifications + + :return: The embeddable HTML string + """ + url = COINBASE_ENDPOINT + '/buttons' + request_data = { + "button": { + "name":name, + "price_string":unicode(price), + "price_currency_iso":price_currency, + "button_type":button_type + } + } + if callback_url is not None: + request_data['button']['callback_url'] = callback_url + request_data.update(kwargs) + response = self.session.post(url=url, data=json.dumps(request_data), + params=self.global_request_params) + resp_data = response.json() + if not resp_data['success'] or 'button' not in resp_data: + error_msg = 'Error creating button' + if 'errors' in resp_data: + error_msg += ':' + u'\n'.join(resp_data) + else: + error_msg += '.' + raise RuntimeError(error_msg) + return CoinbasePaymentButton(**resp_data['button']) diff --git a/coinbase/models/__init__.py b/coinbase/models/__init__.py index 1c5a3ca..5e13882 100644 --- a/coinbase/models/__init__.py +++ b/coinbase/models/__init__.py @@ -5,4 +5,5 @@ from transfer import CoinbaseTransfer from contact import CoinbaseContact from user import CoinbaseUser -from error import CoinbaseError \ No newline at end of file +from error import CoinbaseError +from button import CoinbasePaymentButton diff --git a/coinbase/models/button.py b/coinbase/models/button.py new file mode 100644 index 0000000..67a15a9 --- /dev/null +++ b/coinbase/models/button.py @@ -0,0 +1,8 @@ +__author__ = 'mhluongo' + +class CoinbasePaymentButton(object): + + def __init__(self, *args, **kwargs): + for key, value in kwargs.iteritems(): + setattr(self, key, value) + diff --git a/coinbase/tests.py b/coinbase/tests.py index ad22826..acf87d5 100644 --- a/coinbase/tests.py +++ b/coinbase/tests.py @@ -183,4 +183,17 @@ def test_getting_user_details(self): user = self.account.get_user_details() this(user.id).should.equal("509f01da12837e0201100212") - this(user.balance).should.equal(1225.86084181) \ No newline at end of file + this(user.balance).should.equal(1225.86084181) + + @httprettified + def test_creating_a_button(self): + + HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/buttons", + body='''{"button": {"style": "buy_now_large", "code": "b123456783q812e381cd9d39a5783277", "name": "Test Button", "info_url": null, "text": "Pay With Bitcoin", "price": {"cents": 2000, "currency_iso": "USD"}, "include_email": false, "custom": "", "cancel_url": null, "auto_redirect": false, "success_url": null, "variable_price": false, "include_address": false, "callback_url": null, "type": "buy_now", "choose_price": false, "description": ""}, "success": true}''', + content_type='text/json') + + button = self.account.create_button('Test Button', '20.00', 'USD') + + this(button.code).should.equal('b123456783q812e381cd9d39a5783277') + this(button.name).should.equal('Test Button') + this(button.price['cents']).should.equal(2000) From db3fcfbe68d6fa2f45eaf3a8afb838013326f80e Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Thu, 13 Mar 2014 09:57:41 -0400 Subject: [PATCH 3/3] Fix a bug using optional kwargs to create buttons. --- coinbase/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coinbase/__init__.py b/coinbase/__init__.py index 1a47dd4..58a7284 100644 --- a/coinbase/__init__.py +++ b/coinbase/__init__.py @@ -499,7 +499,7 @@ def create_button(self, name, price, price_currency='BTC', } if callback_url is not None: request_data['button']['callback_url'] = callback_url - request_data.update(kwargs) + request_data['button'].update(kwargs) response = self.session.post(url=url, data=json.dumps(request_data), params=self.global_request_params) resp_data = response.json()