使用ASP.NET Core MVC Web API的Xamarin.Forms PCL中的Stripe.net

时间:2017-10-13 10:40:55

标签: xamarin.forms stripe.net

我正在尝试使用ASP.NET Core MVC Web API将Stripe.net实现到我的Xamarin.Forms PCL中。目标是处理来自用户的信用卡付款。我的Web API在http://localhost:port上本地运行以进行测试。

在PaymentPage中,用户将他们的信用卡信息输入Entry对象,当他们点击提交按钮时,会调用PaymentPageViewModel中的方法来启动逻辑:

async void OnFinishBookingClicked(object sender, System.EventArgs e)
{
    // TODO: Stripe integration
    var viewModel = (PaymentPageViewModel)this.BindingContext;

    await viewModel.ProcessPayment();
}

这是PaymentPageViewModel的一部分:

private readonly IStripeRepository _repository;
private readonly IAPIRepository _api;

public PaymentPageViewModel(IStripeRepository repository, IAPIRepository api)
{
    _repository = repository;
    _api = api;
}

public async Task ProcessPayment()
{
    try
    {
        if (string.IsNullOrEmpty(ExpirationDate))
            ExpirationDate = "09/18";

        var exp = ExpirationDate.Split('/');
        var token = _repository.CreateToken(CreditCardNumber, exp[0], exp[1], SecurityCode);
        await Application.Current.MainPage.DisplayAlert("Test Message", token, "OK");
        await _api.ChargeCard(token, 5.00M);
    }
    catch (Exception ex)
    {
        await Application.Current.MainPage.DisplayAlert("Error", ex.Message, "OK");
    }
}

这就是APIRepository的样子:

public class APIRepository: IAPIRepository
{
    const string Url = "http://localhost:5000";
    private string authorizationKey;

    private async Task<HttpClient> GetClient()
    {
        HttpClient client = new HttpClient();

        if (string.IsNullOrEmpty(authorizationKey))
        {
            authorizationKey = await client.GetStringAsync(Url);
            authorizationKey = JsonConvert.DeserializeObject<string>(authorizationKey);
        }

        client.DefaultRequestHeaders.Add("Authorization", authorizationKey);

        client.DefaultRequestHeaders.Add("Accept", "application/json");

        return client;
    }



    public async Task<string> ChargeCard(string token, decimal amount)
    {
        HttpClient client = await GetClient();

        var json = JsonConvert.SerializeObject(new { token, amount });

        var response = await client.PostAsync("/api/Stripe", new StringContent(json));

        return await response.Content.ReadAsStringAsync();
    }
}

问题是我在等待_api.ChargeCard(令牌,5.00M)期间遇到一系列错误:

第一个异常发生在authorizationKey = await client.GetStringAsync(Url);异常消息如下:

{System.Net.Http.HttpRequestException:404(Not Found),位于/Library/Frameworks/Xamarin.iOS.framework/Versions/11.2.0.11/中的System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()[0x0000a] SRC /单声道/ MCS /类/ System.Net.Http / System.Net.Http / HttpResponseM ...}

我在response = await client.PostAsync(&#34; / api / Stripe&#34;,new StringContent(json));

期间得到另一个异常

{System.InvalidOperationException:请求URI必须是绝对URI或BaseAddress必须在System.Net.Http.HttpClient.SendAsync中设置(System.Net.Http.HttpRequestMessage请求,System.Net.Http.HttpCompletionOption completionOption ,System.Thr ......}

第三个异常发生在viewModel.ProcessPayment()方法的catch块中:

{System.NullReferenceException:对象引用未设置为/Users/carlos/Projects/Zwaby/Zwaby/Services/APIRepository.cs中Zwaby.Services.APIRepository + d _3.MoveNext()[0x00184]中对象的实例:57 ---前面的堆栈跟踪结束...}

在我的Web API项目中,我有一个StripeController,但我的实现可能不完全正确:

[Route("api/Stripe")]
public class StripeController : Controller
{
    private readonly StripeContext _context;

    public StripeController(StripeContext context)
    {
        _context = context;

        if (_context.StripeCharges.Count() == 0)
        {
            _context.StripeCharges.Add(new StripeItem { });
            _context.SaveChanges();
        }
    }

    [HttpGet]
    public IActionResult Get(string key)
    {
        // TODO: implement method that returns authorization key
    }

    [HttpPost]
    public IActionResult Charge(string stripeToken, decimal amount)
    {
        var customers = new StripeCustomerService();
        var charges = new StripeChargeService();

        var customer = customers.Create(new StripeCustomerCreateOptions
        {
            SourceToken = stripeToken
        });

        var charge = charges.Create(new StripeChargeCreateOptions
        {
            Amount = (int)amount,
            Description = "Sample Charge",
            Currency = "usd",
            CustomerId = customer.Id
        });

        return View();
    }

}

为了完整性,我包括了StripeRepository类,这是PaymentPageViewModel的另一个参数:

public class StripeRepository: IStripeRepository
{
    public string CreateToken(string cardNumber, string cardExpMonth, string cardExpYear, string cardCVC)
    {
        StripeConfiguration.SetApiKey("my_test_key");

        //TODO: Wireup card information below

        var tokenOptions = new StripeTokenCreateOptions()
        {
            Card = new StripeCreditCardOptions()
            {
                Number = "4242424242424242",
                ExpirationYear = 2018,
                ExpirationMonth = 10,
                Cvc = "123"
            }
        };

        var tokenService = new StripeTokenService();

        StripeToken stripeToken = tokenService.Create(tokenOptions);

        return stripeToken.Id;
    }
}

非常感谢你!

0 个答案:

没有答案