Как мне передать метаданные через функцию Stripe redirectToCheckout

#stripe-payments

#stripe-платежи

Вопрос:

У меня есть основы работы с платежными намерениями Stripe. Я продаю свое оригинальное произведение искусства. Я хочу иметь возможность отправлять метаданные в процесс оформления заказа. API говорит, что я могу сделать это с помощью payment_intents_data.метаданные показаны здесь:https://support.stripe.com/questions/using-metadata-with-checkout-sessions

 const result = stripe.redirectToCheckout({
            sessionId: session,
            metadata: {
              id: this.props.id,
              title: this.props.title
            }
            });
  

Я получаю сообщение об ошибке, в котором говорится, что stripe.redirectToCheckout не имеет метаданных. Идентификатор сеанса работает нормально.

Как мне передать метаданные? Я вижу в api, что это возможно, но нет примеров того, как это сделать.

Ответ №1:

Моя интеграция с Stripe написана на TypeScript и Angular с использованием AWS Node.js Лямбда-функции через шлюз AWS API. Имея скромные потребности в платежных сервисах, я решил не кодировать страницу оплаты Stripe для своего приложения и вместо этого решил использовать Stripe Checkout. Код пользовательского интерфейса моего приложения вызывает проверку Stripe путем подготовки options объекта и передачи его stripe.redirectToCheckout(options?) .

Ограничения Stripe Checkout

В настоящее время Stripe Checkout не поддерживается metadata в options параметре redirectToCheckout(options) функции, и, насколько я могу судить, нет способа обойти это ограничение. Интерфейс для options параметра, определенный внутри checkout.d.ts из @stripestripe.js библиотеки, предоставляет только следующие поля:

 interface RedirectToCheckoutClientOptions {
/**
 * The URL to which Stripe should send customers when payment is complete.
 * If you’d like access to the Checkout Session for the successful payment, read more about it in our guide on [fulfilling your payments with webhooks](https://stripe.com/docs/payments/checkout/fulfillment#webhooks).
 */
successUrl: string;

/**
 * The URL to which Stripe should send customers when payment is canceled.
 */
cancelUrl: string;

/**
 * An array of objects representing the items that your customer would like to purchase.
 * These items are shown as line items in the Checkout interface and make up the total amount to be collected by Checkout.
 */
lineItems?: Array<{
  /**
   * The ID of the price that the customer would like to purchase. SKU or plan IDs may also be used.
   */
  price?: string;

  /**
   * The quantity of units for the item.
   */
  quantity?: number;
}>;

/**
 * An array of objects representing the items that your customer would like to purchase.
 * These items are shown as line items in the Checkout interface and make up the total amount to be collected by Checkout.
 *
 * @deprecated
 */
items?: Array<{
  /**
   * The ID of the SKU that the customer would like to purchase
   */
  sku?: string;

  /**
   * The ID of the plan that the customer would like to subscribe to.
   */
  plan?: string;

  /**
   * The quantity of units for the item.
   */
  quantity?: number;
}>;

/**
 * The mode of the Checkout Session. Required if using lineItems.
 */
mode?: 'payment' | 'subscription';

/**
 * A unique string to reference the Checkout session.
 * This can be a customer ID, a cart ID, or similar.
 * It is included in the `checkout.session.completed` webhook and can be used to fulfill the purchase.
 */
clientReferenceId?: string;

/**
 * The email address used to create the customer object.
 * If you already know your customer's email address, use this attribute to prefill it on Checkout.
 */
customerEmail?: string;

/**
 * Specify whether Checkout should collect the customer’s billing address.
 * If set to `required`, Checkout will attempt to collect the customer’s billing address.
 * If not set or set to `auto` Checkout will only attempt to collect the billing address when necessary.
 */
billingAddressCollection?: 'auto' | 'required';

/**
 * Provides configuration for Checkout to collect a shipping address from a customer.
 */
shippingAddressCollection?: {
  /**
   * An array of two-letter ISO country codes representing which countries
   * Checkout should provide as options for shipping locations. The codes are
   * expected to be uppercase. Unsupported country codes: AS, CX, CC, CU, HM, IR, KP, MH, FM, NF, MP, PW, SD, SY, UM, VI.
   */
  allowedCountries: string[];
};

/**
 * The [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag) of the locale to display Checkout in.
 * Default is `auto` (Stripe detects the locale of the browser).
 */
locale?: CheckoutLocale;

/**
 * Describes the type of transaction being performed by Checkout in order to customize relevant text on the page, such as the **Submit** button.
 * `submitType` can only be specified when using using line items or SKUs, and not subscriptions.
 * The default is `auto`.
 */
submitType?: 'auto' | 'book' | 'donate' | 'pay';
}
  

Два API

Запутанная часть (по крайней мере, для меня) заключается в том, что в документации Stripe четко не указано, что существуют (по крайней мере) два разных API с разными подходами, которые не предназначены для совместной работы.

Более крупный и полнофункциональный API предназначен для Node.js Интеграция (или другого общего внутреннего сервера), при которой пользовательский интерфейс выполняет платежные вызовы для приложения Node.js серверная часть, которая, в свою очередь, вызывает Stripe для обработки платежей.

API Stripe Checkout очень ограничен и подходит для интеграции непосредственно с клиентом (например, для обработки платежа этот API «изначально» не требует какой-либо серверной части для вызова методов обработки платежей Stripe). Причина, по которой я квалифицирую инструкцию Stripe Checkout как не требующую наличия Node.js серверная часть «изначально» заключается в том, что после того, как Stripe отобразит их простой / стандартный экран оплаты, и пользователь произведет платеж, я бы не рекомендовал пытаться завершить процесс оплаты через ваш код пользовательского интерфейса и вместо этого реализовать веб-ссылки Stripe (используя Node.js серверная часть (или, в моем случае, функции AWS Lambda за шлюзом AWS)). Конечные точки Webhook, которые вы регистрируете в Stripe, которые будут вызываться по мере обработки платежа. В моем случае, как только redirectToCheckout(options) функция перенаправляет на URL-адреса, подтверждающие успех моего приложения или отмененные, пользовательский интерфейс кодируется для опроса одной из моих функций AWS endpoint Lambda, которая в конечном итоге подтверждает или не подтверждает, что платеж был завершен.

Искусственная пауза

Ошибка, которую я допустил (у меня был опыт обучения), заключалась в попытке использовать Node.js Библиотеки Stripe непосредственно в моем приложении пользовательского интерфейса… (Я смог включить библиотеку Stripe Checkout в свое приложение, почему бы также не импортировать Node.js Библиотека Stripe?) Я думаю, что это можно было бы заставить работать, но зависимости, которые ожидает библиотека Stripe, будут доступны, потому что она предполагает Node.js установка также должна быть импортирована в ваш пользовательский интерфейс… Я быстро отказался от этого подхода, потому что казалось, что я покупаю кошмар обслуживания зависимостей на длительный срок … другие более бесстрашные разработчики могут захотеть / быть достаточно умелыми для работы с управлением зависимостями… но не я.

Рекомендация:

Если вам нужно передать metadata для оплаты Stripe, я бы рекомендовал не использовать функцию Stripe Checkout redirectToCheckout(options) … вместо этого создайте свою собственную страницу оплаты, которая передается metadata вашему бэкэнду, который, в свою очередь, использует полный Stripe API для обработки вашего платежа.

Запрос на улучшение

Возможно, в какой-то момент Stripe расширит функциональность Stripe Checkout для поддержки передачи metadata , а также будет поддерживать типы платежей, отличные от кредитных карт…

Как минимум, я бы рекомендовал Stripe свободно размещать перекрестные ссылки (или предупреждения) в документации обоих API, чтобы было очевидно, что они не предназначены для совместного использования с клиентом приложения.

Ответ №2:

Если вы хотите включить метаданные в PaymentIntent, созданный во время CheckoutSession, вам придется включить его во время создания CheckoutSession, а не в redirectToCheckout . При создании CheckoutSession вы можете использовать payment_intent_data.metadata ( https://stripe.com/docs/api/checkout/sessions/create?lang=python#create_checkout_session-payment_intent_data-metadata). Затем вы можете продолжить вызов redirectToCheckout , указав только идентификатор сеанса.

Комментарии:

1. независимо от того, что я пытаюсь, я не могу заставить свое представление django принимать метаданные, я получаю эти ошибки: Получен неизвестный параметр: line_items [0] [метаданные или получен неизвестный параметр: line_items [0] [payment_intent_data.metadata] в зависимости от того, добавляю ли я payment_intent_data.metadata или просто метаданные к элементу строки

2. Вот тут-то и возникает ваша проблема — platform_intent_data.metadata это не дочерний параметр line_items . Это отдельная вещь, и ее следует передавать в вызов Create CheckoutSession в качестве собственного параметра.

3. Я также думаю, что я использую оформление заказа вместо намерений оплаты. Итак, используя intents, я должен создать intent на сервере, а также на сеансе?

4. Нет, нет необходимости создавать намерение на сервере перед сеансом. Пока вы создаете сеанс в режиме «оплата», он будет генерировать для вас PaymentIntent. Передавая payment_intent_data.metadata , вы просто сообщаете Stripe, что должно быть включено в генерируемый им PaymentIntent.

5. На случай, если кто-то пытается сделать это в режиме подписки, вы не сможете. stripe.error.InvalidRequestError: Request req_xyz123: You can not pass payment_intent_data in subscription mode.