Stripe中的延迟付款连接到未知用户

时间:2019-06-25 23:01:00

标签: c# stripe-payments

我正在编写一项服务,该服务允许用户注册课程,但在注册时可能不知道班主任,但我需要创建待处理的费用以确保将向该老师付款。稍后,我想更新待办事项并设置完成日期,例如更新讲师帐户ID和课程结束后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);

我想先创建一个没有目的地的待处理费用,在完成之前,我将更新用户以将其发送到。

我假设只是一个更新过程,请在PaymentIntent上调用Get并更新发件人。

我的困惑集中在三个方面。

  1. API如何知道我被允许代表用户发送的用户? 例如,我只提供一个accountId。注册后,api是否可以完全控制其他帐户?

  2. 如何创建待定费用以确保教师获得付款,创建付款意向时会发生这种情况吗?

  3. 如何完成交易(现在,或者最好是有将来的日期)

2 个答案:

答案 0 :(得分:1)

我最近使用Stripe Connect创建了一个完整的共享经济平台,因此我对此非常熟悉。

向用户收费::在用户安排课程后,您需要为用户创建常规收费。在creating charges上阅读此内容。这将向用户收取$ X,并将其保留在平台帐户中,而无需进行转移。

向讲师付款:您需要使用source_transaction创建单独的转帐,以将钱汇入讲师的帐户。 source_transaction基本上只会从您先前向客户收取的费用中转帐。您可以了解有关here的更多信息。

关于将资金持有24小时,如果您使用source_transaction,则由于处理,这笔钱要到2天后才能用于付款。您可以阅读有关该here的更多信息。如果您希望它变得更快可用,则有两种选择。您既可以启用Instant Payout(我不建议这样做),也可以在平台条带余额中保留一笔准备金,以支付一日的中转费用,然后您可以在没有source_transaction的情况下进行转移。

答案 1 :(得分:1)

好的,所以在问了几个问题并阅读了api文档之后。有几种方法可以做到这一点。 @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,以便他们可以在此处输入卡信息来创建令牌。