He estado tratando de pasar metadatos a través stripe.checkout.Session.create()
así:
stripe.api_key = STRIPE_SECRET_KEY payments_blueprint = Blueprint('payments', __name__, url_prefix='/payments') @payments_blueprint.route('/checkout', methods=['POST']) def create_checkout_session(): try: checkout_session = stripe.checkout.Session.create( metadata=dict(key='val'), payment_method_types=['card'], line_items=request.form.get("lineItems", LINE_ITEMS), success_url=f'{request.environ["HTTP_ORIGIN"]}/success', cancel_url=f'{request.environ["HTTP_ORIGIN"]}/cancel', mode='payment' ) return redirect(checkout_session.url, code=HTTPStatus.SEE_OTHER) except stripe.error.InvalidRequestError as err: return redirect(f'{request.environ["HTTP_ORIGIN"]}/error', code=HTTPStatus.MOVED_PERMANENTLY)
y ni las respuestas de stripe ni los eventos que pasan a través de mi webhook contienen metadatos, aunque el evento se registra en la consola de stripe para la solicitud y la respuesta contienen:
"metadata": { "key": "val" },...
Estoy escuchando todos los eventos usando stripe listen --forward-to localhost:8000/hooks/ --print-json
y todo lo que hace el punto final en /hooks es imprimir el evento en la salida estándar. nada más.
Me gustaría que estos metadatos pasen a través de mi serie de webhooks de validación de reservas. haciendo referencia a esto:
https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-metadata
Básicamente, estoy siguiendo estos documentos, enviando metadatos a través de la llamada para checkout.Session.create()
, y luego no veo estos metadatos. Intenté usar el constructor dict()
, usando la sintaxis de dict en su lugar ( {"key":"val"}
), creando una variable y configurándola en este dict antes de pasarla a través de la función, y cualquier otra forma que se me ocurra para pasar este diccionario de metadatos, pero no lo he recuperado de stripe.
Aquí está el enlace que he configurado donde se reenvían estos eventos:
class TestHook(Resource): def post(self): event = stripe.Event.construct_from( json.loads(request.data), stripe.api_key ).to_dict() print(event['type']) pprint(event['data']['object'])
Y la salida a stdout:
payment_intent.created {'amount': 20000, 'amount_capturable': 0, 'amount_received': 0, 'application': None, 'application_fee_amount': None, 'canceled_at': None, 'cancellation_reason': None, 'capture_method': 'automatic', 'charges': {}, 'client_secret': 'pi_3JTYxxxx7t', 'confirmation_method': 'automatic', 'created': 1630184808, 'currency': 'usd', 'customer': None, 'description': None, 'id': 'pi_3JTYxxxxVm4', 'invoice': None, 'last_payment_error': None, 'livemode': False, 'metadata': <StripeObject at 0x105c061d0> JSON: {}, 'next_action': None, 'object': 'payment_intent', 'on_behalf_of': None, 'payment_method': None, 'payment_method_options': {'card': {'installments': None, 'network': None, 'request_three_d_secure': 'automatic'}}, 'payment_method_types': ['card'], 'receipt_email': None, 'review': None, 'setup_future_usage': None, 'shipping': None, 'source': None, 'statement_descriptor': None, 'statement_descriptor_suffix': None, 'status': 'requires_payment_method', 'transfer_data': None, 'transfer_group': None} checkout.session.completed {'allow_promotion_codes': None, 'amount_subtotal': 20000, 'amount_total': 20000, 'automatic_tax': {'enabled': False, 'status': None}, 'billing_address_collection': None, 'cancel_url': 'http://localhost:9000/#/guides/cozumel-buzos-del-caribe/trips/7-day-dive?cancelpayment=true', 'client_reference_id': None, 'currency': 'usd', 'customer': 'cus_K7oxxxguu', 'customer_details': {'email': 'abc@gmail.com', 'tax_exempt': 'none', 'tax_ids': []}, 'customer_email': None, 'id': 'cs_test_b1Yxxx9dM', 'livemode': False, 'locale': None, 'metadata': <StripeObject at 0x103d64a40> JSON: {}, 'mode': 'payment', 'object': 'checkout.session', 'payment_intent': 'pi_3JTYxxxVm4', 'payment_method_options': <StripeObject at 0x103d648b0> JSON: {}, 'payment_method_types': ['card'], 'payment_status': 'paid', 'setup_intent': None, 'shipping': None, 'shipping_address_collection': None, 'submit_type': None, 'subscription': None, 'success_url': 'http://localhost:9000/#/payment/success', 'total_details': {'amount_discount': 0, 'amount_shipping': 0, 'amount_tax': 0}, 'url': None}
en todos estos eventos, los metadatos son 'metadata': <StripeObject at 0x103d64a40> JSON: {}
¿Qué quiere decir exactamente con "respuesta de sesión" aquí? ¿Puede dar un ejemplo?
Para el webhook, ¿a qué type
de evento exacto estás suscrito? Si, por ejemplo, escuchas payment_intent.succeeded
en lugar de checkout.session.completed
, se esperaría que los metadata
de la sesión no estuvieran presentes. Opcionalmente, puede proporcionar metadata
a la intención de pago subyacente mediante payment_intent_data[metadata][key]=val
, que luego se incluirían en los cuerpos de eventos de la intención de pago.
Después de pasar un tiempo con la gente de Stripe en su discordia (son muy útiles), descubrí que los metadatos publicados en la sesión de pago, usando el método descrito en la pregunta, deberían persistir pero solo en el flujo de la sesión de pago. no estaría presente en ningún otro evento (es decir, cargo, Intento de pago u otros flujos). Después de refactorizar mi código, logré ver estos metadatos en el evento checkout_session.complete
, así que como anticipé... hice algo tonto. Sin embargo, una cosa importante a tener en cuenta es que estos metadatos no se verán en ningún evento posterior que no sea la sesión de pago, que es algo que no entendí al principio. El hecho de que los metadatos no estuvieran en los eventos posteriores de la sesión de pago se debió a un problema entre la silla y el teclado, y no haré más preguntas por un tiempo.
Muchas gracias a todos los que intentaron responder y me dirigieron a la raya. esto realmente abrió una lata de gusanos, en el buen sentido.
Esta pregunta ha sido respondida, pero dado que las respuestas no me quedaron claras de inmediato hasta que experimenté más, solo propongo un poco de información adicional para cualquiera que tenga problemas similares.
En el fragmento de creación de sesión a continuación, preste atención a las DOS declaraciones de metadatos:
stripe.checkout.Session.create( success_url=success_url, cancel_url=cancel_url, payment_method_types=["card"], mode="payment", metadata={ "foo": "FOO", }, payment_intent_data={ "metadata": { "bar": "BAR", } }, line_items=[ { "name": product_name, "quantity": quantity, "currency": currency, "amount": unit_price, }, ] )
Para probar los webhooks, utilicé el comando stripe listen --forward-to localhost:/webhook
a través de Stripe CLI y obtuve los siguientes resultados de una transacción de pago exitosa con mi aplicación. Esto es lo que observé:
Mis datos de 'FOO' estaban disponibles en la carga útil recibida de la devolución de llamada del webhook solo para checkout.session.completed
.
Los datos de mi 'BAR' estaban disponibles en la carga útil recibida de la devolución de llamada del webhook para payment_intent.created
, payment_intent.succeeded
y charge.succeeded
solamente.
Ni 'FOO' ni 'BAR' estaban disponibles en customer.created
o customer.updated
.