diff --git a/payments/backends/__init__.py b/payments/backends/__init__.py index b08334d..b0f5ef2 100644 --- a/payments/backends/__init__.py +++ b/payments/backends/__init__.py @@ -4,7 +4,5 @@ from .base import BackendBase, ManualBackend from .paypal import PaypalBackend from .bitcoin import BitcoinBackend from .stripe import StripeBackend -from .coinbase import CoinbaseBackend -from .coingate import CoinGateBackend from .coinpayments import CoinPaymentsBackend diff --git a/payments/backends/coinbase.py b/payments/backends/coinbase.py deleted file mode 100644 index 92d569f..0000000 --- a/payments/backends/coinbase.py +++ /dev/null @@ -1,110 +0,0 @@ -import json -from ipaddress import IPv4Address, IPv4Network - -from django.shortcuts import redirect -from django.utils.translation import ugettext_lazy as _ -from django.urls import reverse -from django.conf import settings as project_settings - -from .base import BackendBase - - -class CoinbaseBackend(BackendBase): - backend_id = 'coinbase' - backend_verbose_name = _("Coinbase") - backend_display_name = _("Bitcoin with CoinBase") - - def __init__(self, settings): - self.sandbox = settings.get('SANDBOX', False) - if self.sandbox: - default_site = 'https://sandbox.coinbase.com/' - default_base = 'https://api.sandbox.coinbase.com/' - else: - default_site = 'https://www.coinbase.com/' - default_base = 'https://api.coinbase.com/' - - self.currency = settings.get('CURRENCY', 'EUR') - self.key = settings.get('KEY') - self.secret = settings.get('SECRET') - self.base = settings.get('BASE_URL', default_base) - self.site = settings.get('SITE_URL', default_site) - - self.callback_secret = settings.get('CALLBACK_SECRET') - self.callback_source_ip = settings.get('CALLBACK_SOURCE', '54.175.255.192/27') - - if not self.key or not self.secret or not self.callback_secret: - return - - from coinbase.wallet.client import Client - self.client = Client(self.key, self.secret, self.base) - self.backend_enabled = True - - def new_payment(self, payment): - ROOT_URL = project_settings.ROOT_URL - - months = int(payment.time.days / 30) - username = payment.user.username - - amount_str = '%.2f' % (payment.amount / 100) - name = "%d months for %s" % (months, username) - checkout = self.client.create_checkout( - amount=amount_str, - currency=self.currency, - name=name, - success_url=ROOT_URL + reverse('payments:view', args=(payment.id,)), - cancel_url=ROOT_URL + reverse('payments:cancel', args=(payment.id,)), - metadata={'payment_id': payment.id}, - ) - embed_id = checkout['embed_code'] - payment.backend_data['checkout_id'] = checkout['id'] - payment.backend_data['embed_code'] = checkout['embed_code'] - return redirect(self.site + 'checkouts/' + embed_id + - '?custom=' + str(payment.id)) - - def callback(self, Payment, request): - if self.callback_source_ip: - if ('.' in request.META['REMOTE_ADDR']) != ('.' in self.callback_source_ip): - print("source IP version") - print(repr(request.META.get('REMOTE_ADDR'))) - print(repr(self.callback_source_ip)) - return False # IPv6 TODO - net = IPv4Network(self.callback_source_ip) - if IPv4Address(request.META['REMOTE_ADDR']) not in net: - print("source IP") - return False - - secret = request.GET.get('secret') - if secret != self.callback_secret: - print("secret") - return False - - data = json.loads(request.body.decode('utf-8')) - order = data.get('order') - - if not order: - # OK but we don't care - print("order") - return True - - id = order.get('custom') - try: - payment = Payment.objects.get(id=id) - except Payment.DoesNotExist: - # Wrong ID - Valid request, ignore - print("wrong payment") - return True - - button = order.get('button') - if not button: - # Wrong structure. - print("button") - return False - - payment.status = 'confirmed' - payment.save() - payment.user.vpnuser.add_paid_time(payment.time) - payment.user.vpnuser.on_payment_confirmed(payment) - payment.user.vpnuser.save() - return True - - diff --git a/payments/backends/coingate.py b/payments/backends/coingate.py deleted file mode 100644 index f4cab72..0000000 --- a/payments/backends/coingate.py +++ /dev/null @@ -1,137 +0,0 @@ -import string -import random -import requests -import logging - -from django.shortcuts import redirect -from django.utils.translation import ugettext_lazy as _ -from django.urls import reverse -from django.conf import settings as project_settings - -from .base import BackendBase - -logger = logging.getLogger(__name__) -prng = random.SystemRandom() - - -def generate_token(length=16): - charset = string.digits + string.ascii_letters - return ''.join([prng.choice(charset) for _ in range(length)]) - - -class CoinGateBackend(BackendBase): - backend_id = 'coingate' - backend_verbose_name = _("CoinGate") - backend_display_name = _("Cryptocurrencies") - backend_has_recurring = False - - def __init__(self, settings): - self.api_token = settings.get('api_token') - if not self.api_token: - return - - self.currency = settings.get('currency', 'EUR') - self.title = settings.get('title', 'VPN Payment') - - if settings.get('sandbox'): - self.sandbox = True - self.api_base = "https://api-sandbox.coingate.com" - else: - self.sandbox = False - default_base = "https://api.coingate.com" - self.api_base = settings.get('api_base', default_base) - - self.backend_enabled = True - - def _post(self, endpoint, **kwargs): - headers = { - 'Authorization': 'Token ' + self.api_token, - } - url = self.api_base + endpoint - response = requests.post(url, headers=headers, **kwargs) - response.raise_for_status() - j = response.json() - return j - - def new_payment(self, payment): - root_url = project_settings.ROOT_URL - assert root_url - - token = generate_token() - - order = self._post('/v2/orders', data={ - 'order_id': str(payment.id), - 'price_amount': payment.amount / 100, - 'price_currency': self.currency, - 'receive_currency': self.currency, - 'title': self.title, - 'callback_url': root_url + reverse('payments:cb_coingate', args=(payment.id,)), - 'cancel_url': root_url + reverse('payments:cancel', args=(payment.id,)), - 'success_url': root_url + reverse('payments:view', args=(payment.id,)), - 'token': token, - }) - - url = order['payment_url'] - - payment.backend_extid = order['id'] - payment.backend_data['coingate_id'] = order['id'] - payment.backend_data['coingate_url'] = url - payment.backend_data['coingate_token'] = token - payment.save() - - return redirect(url) - - def callback(self, payment, request): - post_data = request.POST - - # Verify callback authenticity - - saved_token = payment.backend_data.get('coingate_token') - if not saved_token: - logger.debug("payment does not have a coingate_token") - return False - - token = post_data.get('token') - if token != saved_token: - logger.debug("unexpected token (%r != %r)", token, saved_token) - return False - - order_id = post_data.get('order_id') - if order_id != str(payment.id): - logger.debug("unexpected order_id (%r != %r)", order_id, str(payment.id)) - return False - - # Handle event - status = post_data.get('status') - if status == 'new' or status == 'pending': - payment.update_status('new') - elif status == 'confirming': - payment.update_status('new', _("Confirming transaction")) - elif status == 'paid': - if payment.status in {'new', 'cancelled', 'error'}: - # we don't have the exact converted amount, but it's not - # important. settings to the requested amount for consistency - payment.paid_amount = payment.amount - payment.confirm() - elif status == 'invalid' or status == 'expired': - if payment.status != 'confirmed': - payment.update_status('cancelled') - elif status == 'refunded': - if payment.status == 'confirmed': - payment.refund() - else: - logger.debug("unexpected payment status: %r", status) - return False - - payment.save() - return True - - def get_ext_url(self, payment): - if not payment.backend_extid: - return None - if self.sandbox: - return 'https://sandbox.coingate.com/account/orders/%s' % payment.backend_extid - else: - return 'https://coingate.com/account/orders/%s' % payment.backend_extid - -