Отсроченный платеж в Stripe Connect с неизвестным пользователем - PullRequest
2 голосов
/ 26 июня 2019

Я пишу сервис, который позволяет пользователям записываться на занятия, во время регистрации преподаватель класса может быть неизвестен, но мне нужно создать ожидающий платеж, чтобы гарантировать, что преподавателю заплатят. Позже я хочу обновить ожидающие и установить дату завершения, например, обновить идентификатор учетной записи преподавателя и через 24 часа после окончания класса заплатить преподавателю

Я пытаюсь понять, как это сделать, но документация по API, похоже, не помогает.

У меня есть сервис для создания платежных статей, например:

var paymentIntentService = new PaymentIntentService();
var paymentIntentTransferDataOptions = new PaymentIntentTransferDataOptions();

var options = new PaymentIntentCreateOptions
{
    Amount = paymentIntentTransactionOptions.AmountInCents,
    Currency = DEFAULT_TRANSACTION_CURRENCY,
    ApplicationFeeAmount = this.CalculateApplicationFee(paymentIntentTransactionOptions),
    ReceiptEmail = "", // TODO Obtain this from the Logged in user
    PaymentMethodTypes = new List<string> { "card" },
};

var requestOptions = new RequestOptions();
requestOptions.IdempotencyKey = INTENT_IDEM_PREFIX + paymentIntentTransactionOptions.TransactionId;
var paymentIntent = await paymentIntentService.CreateAsync(options, requestOptions);

Я хотел бы сначала создать ожидающий платеж без указания пункта назначения, а до его завершения я обновлю пользователя, чтобы отправить его.

Процесс обновления, который я хотел бы просто вызвать, вызвать Get на PaymentIntent и обновить отправителя.

Моя путаница лежит вокруг 3 областей.

  1. Как API узнает, какого пользователя мне разрешено отправлять от имени пользователя? например, я просто предоставляю accountId. Имеет ли API полный контроль над другими учетными записями после регистрации?

  2. Как я могу создать ожидающий платеж, чтобы инструктор получил оплату, происходит ли это при создании платежного намерения?

  3. Как завершить транзакцию (сейчас или предпочтительнее с будущей датой)

Ответы [ 2 ]

1 голос
/ 22 июля 2019

Хорошо, поэтому после того, как вы зададите еще несколько вопросов и прочитаете api docs. Есть несколько способов сделать это. Ответ @nachshonf сделает работу. Однако, если я использую переводы и отдельные сборы, Платформа будет нести ответственность за сборы и возврат Stripe.

Вместо этого я придумал более сложный способ сделать это, но в долгосрочной перспективе у меня будет меньше головной боли. По сути, я создаю удержание через платформу, а затем, когда инструктор будет разрешен, попросит выдать еще одно поручение для инструктора. Таким образом, все споры проходят через инструктора.

Во-первых, я создам трюм через платформу, это довольно просто

public Task<PaymentIntent>CreatePlatformHoldAsync(long amountInCents, string customerId,
    string paymentMethodId, string idem = null, string currency = DEFAULT_TRANSACTION_CURRENCY)
{
    var paymentIntentService = new PaymentIntentService();
    var options = new PaymentIntentCreateOptions
    {
        Amount = amountInCents,
        Currency = currency,
        //ReceiptEmail = "", // TODO Obtain this from the Logged in user
        PaymentMethodTypes = new List<string> { "card" },
        CustomerId = customerId,
        PaymentMethodId = paymentMethodId,
        CaptureMethod = "manual",
    };

    var requestOptions = new RequestOptions { IdempotencyKey = idem };
    return paymentIntentService.CreateAsync(options, requestOptions);
}

/// <summary>
/// Confirm a payment intent, on the platform or sellerAccount
/// </summary>
/// <param name="sellerStripeAccountId">optional, omit for the platform confirm</param>
public Task<PaymentIntent> ConfirmPaymentAsync(string paymentIntentId,
    string sellerStripeAccountId = null)
{
    var paymentIntentService = new PaymentIntentService();
    var paymentIntentConfirmOptions = new PaymentIntentConfirmOptions();

    var options = new RequestOptions
    {
        StripeAccount = sellerStripeAccountId
    };

    return paymentIntentService.ConfirmAsync(paymentIntentId, 
        paymentIntentConfirmOptions, options);
}

Сначала создайте удержание, затем подтвердите его для авторизации платежей. Тогда я создам еще один заряд для инструктора

public Task<PaymentIntent> CreateDestinationChargeAsync(long amountInCents, long applicationFeeInCents, 
    string paymentMethodId, string destinationAccountId, string idem = null, 
    string currency = DEFAULT_TRANSACTION_CURRENCY)
{

    var paymentIntentService = new PaymentIntentService();
    var options = new PaymentIntentCreateOptions
    {
        Amount = amountInCents,
        Currency = currency,
        ApplicationFeeAmount = applicationFeeInCents,
        //ReceiptEmail = "", // TODO Obtain this from the Logged in user
        PaymentMethodTypes = new List<string> { "card" },
        PaymentMethodId = paymentMethodId,
    };

    var requestOptions = new RequestOptions
    {
        IdempotencyKey = idem,
        StripeAccount = destinationAccountId
    };

    return paymentIntentService.CreateAsync(options, requestOptions);
}

После оплаты вы можете отменить удержание платформы или подождать 7 дней, пока удержание не прекратится.

Изменить для использования

public async Task<Customer> CreateCustomerAsync(string email, string sourceToken)
{
    var options = new CustomerCreateOptions
    {
        Email = email, // "paying.user@example.com",
        Source = sourceToken,
    };
    var service = new CustomerService();
    return await service.CreateAsync(options);
}

/// <summary>
/// Creates a payment method for a customer on the sellers stripe account 
/// </summary>
/// <returns></returns>
public async Task<PaymentMethod> CreatePaymentMethodAsync(string customerId, string paymentMethodId,
    string stripeConnectAccountId)
{
    var paymentMethodService = new PaymentMethodService();
    var paymentMethodOptions = new PaymentMethodCreateOptions
    {
        CustomerId = customerId,
        PaymentMethodId = paymentMethodId
    };

    var requestOptions = new RequestOptions()
    {
        StripeAccount = stripeConnectAccountId
    };

    return await paymentMethodService.CreateAsync(paymentMethodOptions, requestOptions);
}

Использование:

//set destination here
var destinationAccountId = "";   

var configuration = this.GetConfiguration();
StripeConfiguration.ApiKey = configuration["Stripe:ClientSecret"];
//This is the name of the service which I define the methods above
var stripeService = new StripeConnectService(configuration);
//"tok_mastercard" is a test value to represent a paymentToken
var customer = await stripeService.CreateCustomerAsync("CustomerEmail@gmail.com", "tok_mastercard");
var sharedPaymentMethod = await stripeService.CreatePaymentMethodAsync(customer.Id, 
    customer.DefaultSourceId, destinationAccount.AccountId);
var paymentIntent = await stripeService.CreateDestinationChargeAsync(1000, 100, 
    sharedPaymentMethod.Id, destinationAccountId);
await stripeService.ConfirmPaymentAsync(paymentIntent.Id, destinationAccountId);

Это примеры, и они не предназначены для производства. Я использую их только для проверки потока.

Примечание: токен оплаты представляет клиента. Я не реализовал способ получения токена оплаты, но, похоже, вам понадобится stripe.js, чтобы они могли ввести туда данные карты для создания токена.

1 голос
/ 26 июня 2019

Я недавно создал целую платформу для совместного использования ресурсов с Stripe Connect, поэтому я довольно хорошо с ней знаком.

Зарядка пользователя: Вам нужно будет создать обычную плату дляпользователь после того, как они планируют класс.Прочитайте это на создание сборов .Это будет взимать с пользователя $ X и удерживать его в учетной записи платформы, но при этом не передавать.

Оплата инструктору: Вам потребуется создать отдельный перевод, используя source_transaction для отправкиденьги на счет инструктора.source_transaction в основном будет осуществлять перевод только с суммы, которую вы сделали ранее с клиента.Вы можете прочитать больше об этом здесь .

Что касается удержания средств в течение 24 часов, если вы используете source_transaction, деньги не будут доступны для выплаты в течение 2 дней после обработки,Вы можете прочитать больше об этом здесь .Если вы хотите, чтобы он стал доступным быстрее, у вас есть 2 варианта.Либо вы можете включить Мгновенную выплату (что я не рекомендую), либо вы можете иметь резервный баланс в балансе полосы вашей платформы для покрытия однодневного переноса, а затем вы можете осуществлять переводы без source_transaction.

...