示例#1
0
async def webhook(payload: dict = Body(...), X_CC_Webhook_Signature: str = Header(None), User_Agent: str = Header(None)):
	try:
		if User_Agent != 'weipay-webhooks':
			raise UnauthorizedError
		try:
			event = Webhook.construct_event(dumps(payload).encode(), X_CC_Webhook_Signature, CoinbaseCommerceSettings.SHARED_SECRET)
		except (WebhookInvalidPayload, SignatureVerificationError):
			raise UnauthorizedError
		
		order = Order.objects.get(id=event.data.metadata.order)
		if event.type == 'charge:pending':
			if not order.stockRemoved:
				if price_service.remove_stock(order):
					order.orderStatus = 'placed'
					order.stockRemoved = True
				else:
					order.orderStatus = 'to refund'
		elif event.type == 'charge:confirmed':
			order.orderStatus = 'paid'
		elif event.type == 'charge:failed':
			order.orderStatus = 'failed'
			if order.stockRemoved:
				price_service.add_stock(order)
				order.stockRemoved = False
		elif event.type == 'charge:delayed':
			order.status = 'to refund'
			# TODO: send an email to the user that they payed after expiratin, that the order failed, and they will be refunded (minus transaction fees perhaps)
		order.save()
		return 'ok'
	except UnauthorizedError:
		raise UnauthorizedError().http_exception
	except Exception as e:
		raise e
示例#2
0
def webhooks():
    # event payload
    request_data = request.data.decode('utf-8')
    # webhook signature
    request_sig = request.headers.get('X-CC-Webhook-Signature', None)

    try:
        # signature verification and event object construction
        event = Webhook.construct_event(request_data, request_sig,
                                        WEBHOOK_SECRET)
    except (WebhookInvalidPayload, SignatureVerificationError) as e:
        return str(e), 400

    print("Received event: id={id}, type={type}".format(id=event.id,
                                                        type=event.type))
    print(event)
    order = Order.query.filter_by(id=event.data.id).first()

    if order:
        order.status = event.type
        order.updated_at = datetime.utcnow()
        save_changes(order)

    if event.type == 'charge:confirmed' or event.type == 'charge:resolved':
        user = User.query.filter_by(email=event.data.metadata.email).first()
        if event.data.name == '1.000 Credits':
            modify_credit_balance(user, 1000, 'Bought 1.000 Credits')
        elif event.data.name == '5.000 Credits':
            modify_credit_balance(user, 5000, 'Bought 5.000 Credits')
            assign_role_to_user('free_download', user)
        elif event.data.name == '10.000 Credits':
            modify_credit_balance(user, 10000, 'Bought 10.000 Credits')
            assign_role_to_user('free_download', user)
            assign_role_to_user('realtime_access', user)
        elif event.data.name == '50.000 Credits':
            modify_credit_balance(user, 50000, 'Bought 50.000 Credits')
            assign_role_to_user('free_download', user)
            assign_role_to_user('realtime_access', user)
        elif event.data.name == '100.000 Credits':
            modify_credit_balance(user, 100000, 'Bought 100.000 Credits')
            assign_role_to_user('free_download', user)
            assign_role_to_user('free_delete_user', user)
            assign_role_to_user('realtime_access', user)
    if not order and event.type == 'charge:created':
        order = Order(
            id=event.data.id,
            status=event.type,
            created_at=datetime.strptime(event.data.created_at,
                                         '%Y-%m-%dT%H:%M:%SZ'),
            item=event.data.name,
        )
        if event.data.name == 'chatpic.exposed':
            order.email = '*****@*****.**'
            return 'success', 200
        else:
            order.email = event.data.metadata.email
        save_changes(order)
    #send_mail(order.email,order, event)
    return 'success', 200
示例#3
0
def webhooks():
    request_data = request.data.decode('utf-8')
    request_sig = request.headers.get('X-CC-Webhook-Signature', None)

    try:
        event = Webhook.construct_event(request_data, request_sig,
                                        WEBHOOK_SECRET)
    except (WebhookInvalidPayload, SignatureVerificationError) as e:
        return str(e), 400

    print("Received event: id={id}, type={type}".format(id=event.id,
                                                        type=event.type))
    return 'success', 200
示例#4
0
    def coinbase_webhook():
        # event payload
        request_data = request.data.decode("utf-8")
        # webhook signature
        request_sig = request.headers.get("X-CC-Webhook-Signature", None)

        try:
            # signature verification and event object construction
            event = Webhook.construct_event(request_data, request_sig,
                                            COINBASE_WEBHOOK_SECRET)
        except (WebhookInvalidPayload, SignatureVerificationError) as e:
            LOG.exception("Invalid Coinbase webhook")
            return str(e), 400

        LOG.d("Coinbase event %s", event)

        if event["type"] == "charge:confirmed":
            if handle_coinbase_event(event):
                return "success", 200
            else:
                return "error", 400

        return "success", 200
示例#5
0
 def test_event_construct(self):
     event = Webhook.construct_event(PAYLOAD_STR, SIG_HEADER, SECRET)
     self.assertIsInstance(event, Event)
     self.assertEqual(event.id, '24934862-d980-46cb-9402-43c81b0cdba6')
示例#6
0
 def test_invalid_payload_no_event(self):
     payload_without_event = '{"id":1,"scheduled_for":"2017-01-31T20:50:02Z","attempt_number":1}'
     with self.assertRaises(WebhookInvalidPayload) as context:
         Webhook.construct_event(payload_without_event, SIG_HEADER, SECRET)
     self.assertTrue('Invalid payload provided' in str(context.exception))
示例#7
0
 def test_invalid_payload_not_json(self):
     invalid_payload_str = 'invalid payload'
     with self.assertRaises(WebhookInvalidPayload) as context:
         Webhook.construct_event(invalid_payload_str, SIG_HEADER, SECRET)
     self.assertTrue('Invalid payload provided' in str(context.exception))
def webhook():
	logger.debug('Received HTTP request')
	if request.method == 'POST':
		logger.debug('HTTP request is type POST')

		# event payload
		request_data = request.data.decode('utf-8')

		# webhook signature
		request_sig = request.headers.get('X-CC-Webhook-Signature', None)

		logger.debug('Validating webhook event signature')
		# signature verification and event object construction
		try:
			event = Webhook.construct_event(request_data, request_sig, config.webhook_secret)
		except (WebhookInvalidPayload, SignatureVerificationError) as e:
			return str(e), 400

		logger.info("Received event: id={id}, code={code}, type={type}".format(id=event.id, code=event.data.code, type=event.type))
		# check event.type. We should only receive charge:confirmed. If webhook is misconfigured we want to ignore pending or failed charges.
		if event.type != "charge:confirmed":
			logger.debug('Event is not a confirmed charge. Waiting...')
			return 'Event received', 200

		logger.debug('Processing confirmed charge')

		# Add all payments and divide by tickets price to get number of tickets purchased
		# event.data.payments is a list, usually contains one payment, but might have more than one.
		try:
			logger.debug('Calculating payment total')
			payment_total = 0

			# add all payments in list
			for payment in event.data.payments:
				payment_total += float(payment.value.local.amount)

			logger.debug('Calculating number of tickets')

			# Payment should be exact multiple of ticket_price
			num_tickets = int(payment_total // config.ticket_price)

			# A confirmed charge should have payment_total > 0
			assert(payment_total > 0)

			# num_tickets should be > 0, if ticket_price is set correctly
			assert(num_tickets > 0)

		except Exception as e:
			logger.error(str(e))
			return 'Error processing event: '+str(e), 400


		logger.debug("Payment total: " + str(payment_total))
		logger.debug("Number of tickets: " + str(num_tickets))

		logger.debug('Creating EventBrite discount code '+str(event.data.code))

		# Create a dicsount code, based on the Coinbase charge code
		# Set quantity to num_tickets and discount to 100%
		eventbrite = Eventbrite(config.eventbrite_token)
		result = eventbrite.post_event_discount(
			config.event_id,
			discount_code=event.data.code,
			discount_percent_off=100,
			discount_quantity_available=num_tickets
		)

		# Check result from EventBrite API
		if 'status_code' in result and result.status_code == 400:
			logger.error("Error creating EventBrite discount code: "+str(result))
			return "Error creating EventBrite discount code", 400
		else:
			logger.info("EventBrite success: "+str(result))
			return 'Success', 200