def execute_payment(self, request: HttpRequest, payment: OrderPayment): try: req = self._post('Payment/v1/PaymentPage/Initialize', json=self._get_payment_page_init_body(payment)) req.raise_for_status() except HTTPError: logger.exception('Saferpay error: %s' % req.text) try: payment.info_data = req.json() except: payment.info_data = {'error': True, 'detail': req.text} payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action( 'pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'data': payment.info_data }) raise PaymentException( _('We had trouble communicating with Saferpay. Please try again and get in touch ' 'with us if this problem persists.')) data = req.json() payment.info = json.dumps(data) payment.state = OrderPayment.PAYMENT_STATE_CREATED payment.save() request.session['payment_saferpay_order_secret'] = payment.order.secret return self.redirect(request, data.get('RedirectUrl'))
def execute_payment(self, request: HttpRequest, payment: OrderPayment): try: req = requests.post('https://api.mollie.com/v2/payments', json=self._get_payment_body(payment), headers=self.request_headers) req.raise_for_status() except HTTPError: logger.exception('Mollie error: %s' % req.text) try: payment.info_data = req.json() except: payment.info_data = {'error': True, 'detail': req.text} payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action( 'pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'data': payment.info_data }) raise PaymentException( _('We had trouble communicating with Mollie. Please try again and get in touch ' 'with us if this problem persists.')) data = req.json() payment.info = json.dumps(data) payment.state = OrderPayment.PAYMENT_STATE_CREATED payment.save() request.session['payment_mollie_order_secret'] = payment.order.secret return self.redirect(request, data.get('_links').get('checkout').get('href'))
def orderpayment(order, date, remind_after, reminded=None, old_format=True): op_date = date op = OrderPayment(order=order, amount=11, provider='sepadebit', state=OrderPayment.PAYMENT_STATE_CONFIRMED) info_data = { 'testdata': 'is not deleted', 'account': 'Testaccount', 'iban': 'DE02120300000000202051', 'bic': 'BYLADEM1001', 'reference': 'TESTREF-123' } if old_format: info_data['date'] = op_date.strftime("%Y-%m-%d") info_data['remind_after'] = remind_after.strftime("%Y-%m-%d-%H-%M-%S") info_data['reminded'] = reminded op.info_data = info_data op.save() else: op.info_data = info_data op.save() due_date = SepaDueDate(date=op_date, reminded=reminded, remind_after=remind_after) due_date.payment = op due_date.save() return op
def execute_payment(self, request: HttpRequest, payment: OrderPayment): try: # Get the correct endpoint to consume x_endpoint = self.get_settings_key('x_endpoint') if x_endpoint == 'live': url = 'https://payments.qpaypro.com/checkout/api_v1' else: url = 'https://sandbox.qpaypro.com/payment/api_v1' # Get the message body payment_body = self._get_payment_body(request, payment) # # To save the information befor send # # TO DO: to delete this action because of security issues # payment.order.log_action('pretix.event.order.payment.started', { # 'local_id': payment.local_id, # 'provider': payment.provider, # 'data': payment_body # }) # Perform the call to the endpoint req = requests.post( url, json=payment_body, ) req.raise_for_status() # Load the response to be read data = req.json() # The result is evaluated to determine the next step if not (data['result'] == 1 and data['responseCode'] == 100): raise PaymentException(data['responseText']) # To save the result payment.info = req.json() payment.confirm() except (HTTPError, PaymentException, Quota.QuotaExceededException): logger.exception('QPayPro error: %s' % req.text) try: payment.info_data = req.json() except Exception: payment.info_data = {'error': True, 'detail': req.text} payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action( 'pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'data': payment.info_data }) raise PaymentException( _('We had trouble communicating with QPayPro. Please try again and get in touch ' 'with us if this problem persists.')) return None
def execute_payment(self, request: HttpRequest, payment: OrderPayment): self._init_api() try: source = self._create_source(request, payment) except stripe.error.StripeError as e: if e.json_body and 'err' in e.json_body: err = e.json_body['error'] logger.exception('Stripe error: %s' % str(err)) else: err = {'message': str(e)} logger.exception('Stripe error: %s' % str(e)) payment.info_data = { 'error': True, 'message': err['message'], } payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action('pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'message': err['message'] }) raise PaymentException(_('We had trouble communicating with Stripe. Please try again and get in touch ' 'with us if this problem persists.')) ReferencedStripeObject.objects.get_or_create( reference=source.id, defaults={'order': payment.order, 'payment': payment} ) payment.info = str(source) payment.state = OrderPayment.PAYMENT_STATE_PENDING payment.save() request.session['payment_stripe_order_secret'] = payment.order.secret return self.redirect(request, source.redirect.url)
def execute_payment(self, request: HttpRequest, payment: OrderPayment): self._init_api() try: source = self._create_source(request, payment) except stripe.error.StripeError as e: if e.json_body: err = e.json_body['error'] logger.exception('Stripe error: %s' % str(err)) else: err = {'message': str(e)} logger.exception('Stripe error: %s' % str(e)) payment.info_data = { 'error': True, 'message': err['message'], } payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action('pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'message': err['message'] }) raise PaymentException(_('We had trouble communicating with Stripe. Please try again and get in touch ' 'with us if this problem persists.')) ReferencedStripeObject.objects.get_or_create( reference=source.id, defaults={'order': payment.order, 'payment': payment} ) payment.info = str(source) payment.state = OrderPayment.PAYMENT_STATE_PENDING payment.save() request.session['payment_stripe_order_secret'] = payment.order.secret return self.redirect(request, source.redirect.url)
def execute_payment(self, request: HttpRequest, payment: OrderPayment) -> str: # This method will only be called when retrying payments, e.g. after a payment_prepare call. It is not called # during the order creation phase because this payment provider is a special case. for p in payment.order.positions.all(): # noqa - just a safeguard if p.item.issue_giftcard: raise PaymentException( _("You cannot pay with gift cards when buying a gift card." )) gcpk = payment.info_data.get('gift_card') if not gcpk or not payment.info_data.get('retry'): raise PaymentException("Invalid state, should never occur.") with transaction.atomic(): gc = GiftCard.objects.select_for_update().get(pk=gcpk) if gc.currency != self.event.currency: # noqa - just a safeguard raise PaymentException( _("This gift card does not support this currency.")) if not gc.accepted_by( self.event.organizer): # noqa - just a safeguard raise PaymentException( _("This gift card is not accepted by this event organizer." )) if payment.amount > gc.value: # noqa - just a safeguard raise PaymentException( _("This gift card was used in the meantime. Please try again" )) trans = gc.transactions.create(value=-1 * payment.amount, order=payment.order, payment=payment) payment.info_data = { 'gift_card': gc.pk, 'transaction_id': trans.pk, } payment.confirm()
def execute_payment(self, request: HttpRequest, payment: OrderPayment): pay_data = { "NotificationURL": build_absolute_uri(self.event, 'plugins:pretix_tinkoff:webhook', kwargs={ 'payment': payment.pk }), "SuccessURL": build_absolute_uri(self.event, 'plugins:pretix_tinkoff:return', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(), 'action': 'success' }), "FailURL": build_absolute_uri(self.event, 'plugins:pretix_tinkoff:return', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(), 'action': 'fail' }), 'Amount': int(payment.amount * 100), 'OrderId': "{}-{}".format(self.event.slug.upper(), payment.order.code), 'Description': "Order {}-{}".format(self.event.slug.upper(), payment.order.code), 'DATA': { 'organizer': self.event.organizer.slug, 'event': self.event.slug, 'order': payment.order.code, 'payment': payment.local_id, 'order-full-code': payment.order.full_code }, 'PayType': "O" } try: req = self._init(pay_data) except HTTPError: logger.exception('Tinkoff error: %s' % req) if req['Success'] == False: logger.exception('Tinkoff error: %s' % req) payment.info_data = { 'error': True, 'detail': req } payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action('pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'data': payment.info_data }) raise PaymentException(_('We had trouble communicating with Tinkoff. Please try again and get in touch ' 'with us if this problem persists. Detail: {}'.format(req['Details']))) ReferencedTinkoffTransaction.objects.get_or_create(order=payment.order, payment=payment, reference=req['PaymentId']) LogTransaction(paymentid=req['PaymentId'], order=payment.order, payment=payment, method='get', meta_info=json.dumps(req)) payment.info = json.dumps(req) payment.state = OrderPayment.PAYMENT_STATE_CREATED logger.info('pay_request: {}'.format(pay_data)) logger.info('pay_response: {}'.format(payment.info)) payment.save(update_fields=['info']) return self.redirect(request, req['PaymentURL'])
def execute_payment(self, request: HttpRequest, payment: OrderPayment): request.session['sofort_order_secret'] = payment.order.secret shash = hashlib.sha1(payment.order.secret.lower().encode()).hexdigest() r = sofort.MultiPay( project_id=self.settings.get('project_id'), amount=payment.amount, currency_code=self.event.currency, reasons=[payment.order.full_code, '-TRANSACTION-'], user_variables=[payment.order.full_code], success_url=build_absolute_uri(self.event, 'plugins:pretix_sofort:return', kwargs={ 'order': payment.order.code, 'hash': shash, }) + '?state=success&transaction=-TRANSACTION-', abort_url=build_absolute_uri(self.event, 'plugins:pretix_sofort:return', kwargs={ 'order': payment.order.code, 'hash': shash, }) + '?state=abort&transaction=-TRANSACTION-', timeout_url=build_absolute_uri(self.event, 'plugins:pretix_sofort:return', kwargs={ 'order': payment.order.code, 'hash': shash, }) + '?state=timeout&transaction=-TRANSACTION-', notification_urls=[ build_absolute_uri(self.event, 'plugins:pretix_sofort:webhook') ], ) try: trans = sofort.NewTransaction.from_xml(self._api_call(r.to_xml())) except sofort.SofortError as e: logger.exception('Failure during sofort payment: {}'.format( e.message)) raise PaymentException( _('Sofort reported an error: {}').format(e.message)) except IOError: logger.exception('Failure during sofort payment.') raise PaymentException( _('We had trouble communicating with Sofort. Please try again and get in touch ' 'with us if this problem persists.')) ReferencedSofortTransaction.objects.get_or_create( order=payment.order, reference=trans.transaction, payment=payment) payment.info_data = { 'transaction': trans.transaction, 'status': 'initiated' } payment.save(update_fields=['info']) return self.redirect(request, trans.payment_url)
def execute_payment(self, request: HttpRequest, payment: OrderPayment): currency_type = request.session['payment_ethereum_currency_type'] payment_timestamp = request.session['payment_ethereum_time'] payment_amount = request.session['payment_ethereum_amount'] payment.info_data = { 'currency_type': currency_type, 'time': payment_timestamp, 'amount': payment_amount, } payment.save(update_fields=['info'])
def execute_payment(self, request: HttpRequest, payment: OrderPayment): currency_type = request.session['payment_ethereum_currency_type'] payment_timestamp = request.session['payment_ethereum_time'] truncated_amount_in_wei = request.session['payment_ethereum_amount'] amount_plus_payment_id = truncated_amount_in_wei + payment.id payment.info_data = { 'currency_type': currency_type, 'time': payment_timestamp, 'amount': amount_plus_payment_id, } payment.save(update_fields=['info'])
def payment_prepare(self, request: HttpRequest, payment: OrderPayment) -> Union[bool, str, None]: for p in payment.order.positions.all(): if p.item.issue_giftcard: messages.error( request, _("You cannot pay with gift cards when buying a gift card." )) return try: gc = self.event.organizer.accepted_gift_cards.get( secret=request.POST.get("giftcard")) if gc.currency != self.event.currency: messages.error( request, _("This gift card does not support this currency.")) return if gc.testmode and not payment.order.testmode: messages.error( request, _("This gift card can only be used in test mode.")) return if not gc.testmode and payment.order.testmode: messages.error( request, _("Only test gift cards can be used in test mode.")) return if gc.value <= Decimal("0.00"): messages.error( request, _("All credit on this gift card has been used.")) return payment.info_data = {'gift_card': gc.pk, 'retry': True} payment.amount = min(payment.amount, gc.value) payment.save() return True except GiftCard.DoesNotExist: if self.event.vouchers.filter( code__iexact=request.POST.get("giftcard")).exists(): messages.warning( request, _("You entered a voucher instead of a gift card. Vouchers can only be entered on the first page of the shop below " "the product selection.")) else: messages.error(request, _("This gift card is not known.")) except GiftCard.MultipleObjectsReturned: messages.error( request, _("This gift card can not be redeemed since its code is not unique. Please contact the organizer of this event." ))
def execute_payment(self, request: HttpRequest, payment: OrderPayment): payment.info_data = { 'sender_address': request.session['payment_ethereum_fm_address'], 'currency': request.session['payment_ethereum_fm_currency'], 'time': request.session['payment_ethereum_time'], 'amount': request.session['payment_ethereum_amount'], } payment.save(update_fields=['info']) try: if request.session['payment_ethereum_fm_currency'] == 'ETH': response = requests.get( f'https://api.ethplorer.io/getAddressTransactions/{self.settings.ETH}?apiKey=freekey' # noqa: E501 ) deca = response.json() if len(deca) > 0: for decc in deca: if decc['success'] == True and decc[ 'from'] == request.session[ 'payment_ethereum_fm_address']: # noqa: E501 if decc['timestamp'] > request.session[ 'payment_ethereum_time'] and decc[ 'value'] >= request.session[ 'payment_ethereum_amount']: # noqa: E501 try: payment.confirm() except Quota.QuotaExceededException as e: raise PaymentException(str(e)) else: dec = requests.get( 'https://blockscout.com/poa/dai/api?module=account&action=txlist&address=' + self.settings.DAI) # noqa: E501 deca = dec.json() for decc in deca['result']: if decc['txreceipt_status'] == '1' and decc[ 'from'] == request.session[ 'payment_ethereum_fm_address']: # noqa: E501 # if (decc['timestamp'] > request.session['payment_ethereum_time'] and decc[ # noqa: E501 # 'value'] >= request.session['payment_ethereum_amount']): try: payment.confirm() except Quota.QuotaExceededException as e: raise PaymentException(str(e)) except NameError: pass except TypeError: pass except AttributeError: pass return None
def execute_payment(self, request: HttpRequest, payment: OrderPayment): txn_hash = request.session['payment_ethereum_txn_hash'] txn_hash_bytes = to_bytes(hexstr=txn_hash) currency_type = request.session['payment_ethereum_currency_type'] payment_timestamp = request.session['payment_ethereum_time'] payment_amount = request.session['payment_ethereum_amount'] if Transaction.objects.filter(txn_hash=txn_hash_bytes).exists(): raise PaymentException( f'Transaction with hash {txn_hash} already used for payment') payment.info_data = { 'txn_hash': txn_hash, 'currency_type': currency_type, 'time': payment_timestamp, 'amount': payment_amount, } payment.save(update_fields=['info']) if currency_type == 'ETH': transaction = self.transaction_provider.get_transaction(txn_hash) is_valid_payment = all(( transaction.success, transaction.to == self.settings.ETH, transaction.value >= payment_amount, transaction.timestamp >= payment_timestamp, )) elif currency_type == 'DAI': transfer = self.token_provider.get_ERC20_transfer(txn_hash) is_valid_payment = all(( transfer.success, transfer.to == self.settings.DAI, transfer.value >= payment_amount, transfer.timestamp >= payment_timestamp, )) else: # unkown currency raise ImproperlyConfigured(f"Unknown currency: {currency_type}") if is_valid_payment: with db_transaction.atomic(): try: payment.confirm() except Quota.QuotaExceededException as e: raise PaymentException(str(e)) else: Transaction.objects.create(txn_hash=txn_hash_bytes, order_payment=payment)
def execute_payment(self, request: HttpRequest, payment: OrderPayment): due_date = self._due_date() ref = '%s-%s' % (self.event.slug.upper(), payment.order.code) if self.settings.reference_prefix: ref = self.settings.reference_prefix + "-" + ref try: payment.info_data = { 'account': request.session['payment_sepa_account'], 'iban': request.session['payment_sepa_iban'], 'bic': request.session['payment_sepa_bic'], 'reference': ref, 'date': due_date.strftime("%Y-%m-%d") } payment.confirm( mail_text=self.order_pending_mail_render(payment.order)) except Quota.QuotaExceededException as e: raise PaymentException(str(e)) finally: del request.session['payment_sepa_account'] del request.session['payment_sepa_iban'] del request.session['payment_sepa_bic']
def execute_payment(self, request: HttpRequest, payment: OrderPayment): due_date, reminded = self._due_date_reminded() ref = '%s-%s' % (self.event.slug.upper(), payment.order.code) if self.settings.reference_prefix: ref = self.settings.reference_prefix + "-" + ref try: payment.info_data = { 'account': request.session['payment_sepa_account'], 'iban': request.session['payment_sepa_iban'], 'bic': request.session['payment_sepa_bic'], 'reference': ref, } # add current time to due_date for remind after to take pressure of the cron job due = SepaDueDate.objects.update_or_create( payment=payment, defaults={ 'date': due_date, 'reminded': reminded, 'remind_after': now().astimezone(self.event.timezone).replace( year=due_date.year, month=due_date.month, day=due_date.day) })[0] payment.confirm( mail_text=self.order_pending_mail_render(payment.order)) except Quota.QuotaExceededException as e: due.delete() raise PaymentException(str(e)) finally: del request.session['payment_sepa_account'] del request.session['payment_sepa_iban'] del request.session['payment_sepa_bic']
def execute_payment(self, request: HttpRequest, payment: OrderPayment): self._init_api() if request.session['payment_stripe_token'].startswith('src_'): try: src = stripe.Source.retrieve(request.session['payment_stripe_token'], **self.api_kwargs) if src.type == 'card' and src.card and self._use_3ds(src.card): request.session['payment_stripe_order_secret'] = payment.order.secret source = stripe.Source.create( type='three_d_secure', amount=self._get_amount(payment), currency=self.event.currency.lower(), three_d_secure={ 'card': src.id }, statement_descriptor=ugettext('{event}-{code}').format( event=self.event.slug.upper(), code=payment.order.code )[:22], metadata={ 'order': str(payment.order.id), 'event': self.event.id, 'code': payment.order.code }, redirect={ 'return_url': build_absolute_uri(self.event, 'plugins:stripe:return', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(), }) }, **self.api_kwargs ) ReferencedStripeObject.objects.get_or_create( reference=source.id, defaults={'order': payment.order, 'payment': payment} ) if source.status == "pending": payment.info = str(source) payment.state = OrderPayment.PAYMENT_STATE_PENDING payment.save() return self.redirect(request, source.redirect.url) except stripe.error.StripeError as e: if e.json_body: err = e.json_body['error'] logger.exception('Stripe error: %s' % str(err)) else: err = {'message': str(e)} logger.exception('Stripe error: %s' % str(e)) payment.info_data = { 'error': True, 'message': err['message'], } payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() payment.order.log_action('pretix.event.order.payment.failed', { 'local_id': payment.local_id, 'provider': payment.provider, 'message': err['message'] }) raise PaymentException(_('We had trouble communicating with Stripe. Please try again and get in touch ' 'with us if this problem persists.')) try: self._charge_source(request, request.session['payment_stripe_token'], payment) finally: del request.session['payment_stripe_token']
def execute_payment(self, request: HttpRequest, payment: OrderPayment): self._init_api() if request.session['payment_stripe_token'].startswith('src_'): try: src = stripe.Source.retrieve(request.session['payment_stripe_token'], **self.api_kwargs) if src.type == 'card' and src.card and self._use_3ds(src.card): request.session['payment_stripe_order_secret'] = payment.order.secret source = stripe.Source.create( type='three_d_secure', amount=self._get_amount(payment), currency=self.event.currency.lower(), three_d_secure={ 'card': src.id }, statement_descriptor=ugettext('{event}-{code}').format( event=self.event.slug.upper(), code=payment.order.code )[:22], metadata={ 'order': str(payment.order.id), 'event': self.event.id, 'code': payment.order.code }, redirect={ 'return_url': build_absolute_uri(self.event, 'plugins:stripe:return', kwargs={ 'order': payment.order.code, 'payment': payment.pk, 'hash': hashlib.sha1(payment.order.secret.lower().encode()).hexdigest(), }) }, **self.api_kwargs ) ReferencedStripeObject.objects.get_or_create( reference=source.id, defaults={'order': payment.order, 'payment': payment} ) if source.status == "pending": payment.info = str(source) payment.state = OrderPayment.PAYMENT_STATE_PENDING payment.save() return self.redirect(request, source.redirect.url) except stripe.error.StripeError as e: if e.json_body: err = e.json_body['error'] logger.exception('Stripe error: %s' % str(err)) else: err = {'message': str(e)} logger.exception('Stripe error: %s' % str(e)) payment.info_data = { 'error': True, 'message': err['message'], } payment.state = OrderPayment.PAYMENT_STATE_FAILED payment.save() raise PaymentException(_('We had trouble communicating with Stripe. Please try again and get in touch ' 'with us if this problem persists.')) try: self._charge_source(request, request.session['payment_stripe_token'], payment) finally: del request.session['payment_stripe_token']