我正在尝试使用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;
}
}
非常感谢你!