Flutter Stripe Web с PaymentElement вместо PaymentSheet

Изучив другие варианты, я узнал, что единственный способ решить проблему для моего варианта использования приема платежей по картам в моем веб-приложении Flutter — это использовать пакеты Flutter_stripe и flutter_stripe_web.

Я реализовал оба варианта, чтобы узнать, что Stripe.PaymentSheet НЕ поддерживается в Интернете. :( Благодаря поддержке Stripe я узнал, что вместо PaymentSheet мне следует использовать Stripe.PaymentElement, в то время как остальная часть кода остается прежней, то есть PaymentIntent, внутренняя функция и т. д.

Я попробовал следующий документ (хотя это немного неясно в контексте Flutter/dart), но я просто не могу заполнить недостающие блоки.

Не могли бы вы, ребята, взглянуть и сообщить мне, что я делаю неправильно или какой может быть правильный способ реализации PaymentElement вместо Sheets?

Заранее спасибо.

Мой файл платежа

import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:http/http.dart' as http;

    class StripePayments {
      Future<void> initPaymentSheet(context,
          {required String email, required int amount}) async {
        try {
          // 1. create payment intent on the server
          final response = await http.post(
              Uri.parse(
                  'https://mycloudFunctionUrl/stripePaymentIntentRequest'),
              body: {
                'email': email,
                'amount': amount.toString(),
              });
    
          if (response.statusCode != 200) {
            throw Exception('Failed to create payment intent: ${response.body}');
          }
    
          final jsonResponse = jsonDecode(response.body);
          log('Payment intent response: $jsonResponse');
    
          // 2. Verify the keys and data
          if (jsonResponse['paymentIntent'] == null ||
              jsonResponse['customer'] == null ||
              jsonResponse['ephemeralKey'] == null) {
            throw Exception('Invalid response from server: $jsonResponse');
          }
    
          // 3. initialize the payment sheet
    
          await Stripe.instance.initPaymentSheet(
            paymentSheetParameters: SetupPaymentSheetParameters(
              paymentIntentClientSecret: jsonResponse['paymentIntent'],
              merchantDisplayName: 'Cruise-App',
              customerId: jsonResponse['customer'],
              customerEphemeralKeySecret: jsonResponse['ephemeralKey'],
              style: ThemeMode.light,
            ),
          );
    
          // 4. Present the payment sheet
          await Stripe.instance.presentPaymentSheet();
    
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Payment completed!')),
          );
        } catch (e) {
          if (e is StripeException) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('Error from Stripe: ${e.error.localizedMessage}'),
              ),
            );
          } else if (e is StripeConfigException) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('Stripe configuration error: ${e.message}'),
              ),
            );
          } else {
            print(e.toString());
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('Error: $e')),
            );
          }
        }
      }
    }

Вот как выглядит моя серверная/облачная функция

const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });
const stripe = require("stripe")("sk_test_my_secret_key");

exports.stripePaymentIntentRequest = functions.region("europe-west3").https.onRequest((req, res) => {
  cors(req, res, async () => {
    try {
      let customerId;

      // Gets the customer whose email id matches the one sent by the client
      const customerList = await stripe.customers.list({
        email: req.body.email,
        limit: 1
      });

      // Checks if the customer exists, if not creates a new customer
      if (customerList.data.length !== 0) {
        customerId = customerList.data[0].id;
      } else {
        const customer = await stripe.customers.create({
          email: req.body.email
        });
        customerId = customer.id; // Changed customer.data.id to customer.id
      }

      // Creates a temporary secret key linked with the customer
      const ephemeralKey = await stripe.ephemeralKeys.create(
        { customer: customerId },
        { apiVersion: '2020-08-27' }
      );

      // Creates a new payment intent with amount passed in from the client
      const paymentIntent = await stripe.paymentIntents.create({
        amount: parseInt(req.body.amount),
        currency: 'nok',
        customer: customerId,
      });

      res.status(200).send({
        paymentIntent: paymentIntent.client_secret,
        ephemeralKey: ephemeralKey.secret,
        customer: customerId,
        success: true,
      });

    } catch (error) {
      res.status(404).send({ success: false, error: error.message });
    }
  });
});

Это документация, на которую меня направила команда Stripe, но их служба поддержки говорит в Discord: «Мы не знаем ни дротика, ни флаттера. Не знаю, как это делают люди, которые уже это сделали».

Пожалуйста, предложите! Еще раз спасибо

Можете ли вы предоставить более подробную информацию о том, что не работает? Вы поделились кодом, но не знаете, что вас заблокировало.

hanzo 28.06.2024 23:05

В моем общем коде вы можете увидеть шаг 3 — инициализация платежного листа и шаг 4 — представление платежного листа. Я хочу, чтобы эти функции были реализованы в чем-то, что Stripe называет PaymentElement, чего я не могу найти в методах библиотеки. Так что не уверен, что делать дальше

Firaun 29.06.2024 01:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вы можете напрямую использовать виджет PaymentElement. У меня мало знаний по этому поводу, но это может помочь вам начать работу.

var paymentIntentResult = await createPaymentIntent('100','JYP');
var paymentIntentSecret = paymentIntentResult['client_secret'];

PaymentElement(
        autofocus: true,
        enablePostalCode: true,
        onCardChanged: (_) {},
        clientSecret: paymentIntentSecret ?? '',
)

createPaymentIntent(String amount, String currency) async {
try {
  //Request body
  Map<String, dynamic> body = {
    'amount': calculateAmount(amount),
    'currency': currency,
  };

  //Make post request to Stripe
  var response = await http.post(
    Uri.parse('https://api.stripe.com/v1/payment_intents'),
    headers: {
      'Authorization':
          'Bearer [your_key]',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: body,
  );
  return json.decode(response.body);
} catch (err) {
  throw Exception(err.toString());
}

и используйте это, чтобы вызвать

 OutlinedButton(
          onPressed: () async {
            try {
              await WebStripe.instance
                  .confirmPaymentElement(ConfirmPaymentElementOptions(
                redirect: PaymentConfirmationRedirect.ifRequired,
                confirmParams: ConfirmPaymentParams(return_url: ''),
              ));
            } on Exception catch (e) {
              print(e.toString());
            }
          },
          child: Text('Go'));

это не полный ответ для моего случая, но в большинстве случаев это действительно указывало правильный путь. Спасибо.

Firaun 01.07.2024 23:55

Другие вопросы по теме

Как я могу получить метаданные продукта из сеанса после завершения оформления заказа с помощью Stripe в приложении Spring Boot?
Как получить payMethodId с помощью createPaymentMethod из полосы с помощью React Native?
Решение проблем с проверкой подписи Webhook в Stripe с помощью Express.js
Iframe, у которого есть как разрешить сценарии, так и разрешить то же происхождение для атрибута песочницы, может избежать изолированной программной среды
Использование полосовой проверки для создания подписки БЕЗ немедленной оплаты
Вручную повторить неудачную попытку оплаты подписки с использованием той же карты
Тестовый токен Stripe не работает в тестовой среде
Получение следующего счета за подписку в пробном режиме, без использования счета и без каких-либо способов оплаты
Next.js 14: ошибка неопределенного значения при сериализации продуктов в getServerSideProps
Как обрабатывать обновление подписки на полосу, если уже есть запланированная подписка?