如何在 C# WCF 中接收 Stripe api webhook
Posted
技术标签:
【中文标题】如何在 C# WCF 中接收 Stripe api webhook【英文标题】:How to receive Stripe api webhook in C# WCF 【发布时间】:2019-11-29 10:56:46 【问题描述】:我正在尝试从 Stripe 结帐发布请求接收 webhook。但是 Stripe 文档只显示了 ASP.net 的示例代码,而我使用的是 WCF。 https://stripe.com/docs/payments/checkout/fulfillment#webhooks
这是 Stripe 结账的示例请求。
"created": 1326853478,
"livemode": false,
"id": "evt_00000000000000",
"type": "checkout.session.completed",
"object": "event",
"request": null,
"pending_webhooks": 1,
"api_version": "2019-05-16",
"data":
"object":
"id": "cs_00000000000000",
"object": "checkout.session",
"billing_address_collection": null,
"cancel_url": "https://example.com/cancel",
"client_reference_id": null,
"customer": null,
"customer_email": null,
"display_items": [
"amount": 1500,
"currency": "usd",
"custom":
"description": "Comfortable cotton t-shirt",
"images": null,
"name": "T-shirt"
,
"quantity": 2,
"type": "custom"
],
"livemode": false,
"locale": null,
"payment_intent": "pi_00000000000000",
"payment_method_types": [
"card"
],
"submit_type": null,
"subscription": null,
"success_url": "https://example.com/success"
起初我尝试使用 Stripe.Event 类作为参数。
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
void FromStripeCheckoutWrapped(Event data);
但是所有数据都是空值。 所以,我尝试根据json请求使用我自己的Model类。
public partial class Temperatures
[DataMember]
public long Created get; set;
[DataMember]
public bool Livemode get; set;
[DataMember]
public string Id get; set;
[DataMember]
public string Type get; set;
[DataMember]
public string Object get; set;
[DataMember]
public object Request get; set;
[DataMember]
public long PendingWebhooks get; set;
[DataMember]
public string ApiVersion get; set;
[DataMember]
public Data Data get; set;
...
但他们都没有收到正确的数据。
我尝试使用 String 参数接收的最后一件事,就像我在 *** 但在 Java 中发现的问题一样。 How to Receive Webhook from Stripe in Java 他说他可以用这种方式打印数据。但我做不到。
我让它成功的唯一方法是输入 json 请求中写的每一个参数。我也尝试将 Wrapped 和 Bare 作为 WebMessageBodyStyle。
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
void FromStripeCheckoutWrapped(long created, bool livemode, string id ...);
然后我可以正确获取数据..但是像上面那样做所有事情都太长了。 如何以有效且正确的方式接收 POST 请求? 请同时参考 Java 和 Stripe webhook 文档中的问题。 我只想将 POST 请求读取为 String 对象,而不管请求结构如何,以便我可以解析它。
【问题讨论】:
在DataMember
属性上设置 Name
参数以匹配 JSON 中属性名称的大小写。创建创建
@rene 我试过了,但没用..
请参考以下链接。也许它对你有用。 ***.com/questions/52489002/…
如果您正在寻找最新的 ASP.NET Core MVC 或 ASP.NET Web 表单中的 Stripe checkout 解决方案,请查看演示:techtolia.com/Stripe
【参考方案1】:
当我使用以下 DataContract 类时,反序列化该示例负载没有问题:
[DataContract]
public class Base
[DataMember(Name="livemode")]
public bool Livemode get;set;
[DataMember(Name="object")]
public string @Object get;set;
[DataMember(Name="id")]
public string Id get;set;
[DataContract]
public class Event:Base
[DataMember(Name="created")]
public long Created get;set;
[DataMember(Name="type")]
public string Type get;set;
[DataMember(Name="data")]
public EventData Data get;set;
[DataContract]
public class EventData
[DataMember(Name="object")]
public EventObject EventObject get;set;
[DataContract]
public class EventObject:Base
[DataMember(Name="display_items")]
public Item[] DisplayItems get;set;
[DataContract]
public class Item
[DataMember(Name="amount")]
public double Amount get;set;
[DataMember(Name="currency")]
public string Currency get;set;
我在本服务合同中使用该 DataContract:
[ServiceContract]
interface IContract
[OperationContract]
[WebInvoke(
Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
string StripeWebhook(Event data);
当我为该服务创建实现时:
public class JsonService:IContract
public string StripeWebhook(Event data)
data.Dump("rcvd data");
return "\"result\":\"success\"";
并将其提供给 WebServiceHost:
// keeps the service running
AutoResetEvent are = new AutoResetEvent(false);
void Start()
//netsh http add urlacl url=http://+:8000/json user=USERNAME
using (var serviceHost = new WebServiceHost(typeof(JsonService), new Uri("http://localhost:8000/json")))
serviceHost.AddServiceEndpoint(typeof(IContract), new WebHttpBinding(), "");
serviceHost.Open();
are.WaitOne(); // blocks
serviceHost.Close();
我可以在启动该服务并将 JSON POST 到它后调用它:
void Main()
new Thread(Start).Start();
try
var wc = new WebClient();
wc.Headers.Add("content-type","application/json");
wc.UploadString("http://localhost:8000/json/Stripewebhook", File.ReadAllText(@"example_json_wcf.json")).Dump("response");
catch(WebException e)
e.Dump("raw");
using(var ms = new MemoryStream())
e.Response.GetResponseStream().CopyTo(ms);
Encoding.UTF8.GetString(ms.ToArray()).Dump("error");
Console.WriteLine("Now Running. Enter key will stop the service.");
Console.ReadLine();
are.Set();
这是我在 LinqPad 中的结果:
记住:
裸露或包裹很重要 在(反)序列化套管问题如果反序列化失败,请先尝试序列化您的对象树,然后将该结果与您实际需要的结果进行比较。 或者使用许多 JSON 到 POCO 服务中的一种,例如:http://json2csharp.com/(我不隶属于该服务,它恰好是我的 Google 搜索中弹出的第一个)
【讨论】:
非常感谢!实际上我通过 json2csharp 制作了 DataContract 表单,但格式非常不同。我认为问题出在 Model(Datacontract) 结构上。我没有尝试过继承结构。以上是关于如何在 C# WCF 中接收 Stripe api webhook的主要内容,如果未能解决你的问题,请参考以下文章
在 C# MVC 中使用 Stripe api 兑换促销代码
在 Stripe Customer 对象 C# 中访问元数据时遇到问题
如何在 C# 中正确使用 WCF REST API 上的 Stream 将文件(图像/视频/等)上传到服务器?