Posts tagged with “c#”

A neat way to remove trailing zeros from a decimal number in C#

We can get unexpected trailing zeros when we serialzie an object with decimal properties, normally it will not hurt. However, it does hurt when we want to compare two objects by serializing them to JSON string. I tried a few solutions and finally find the following one is the best.

public static decimal Normalize(this decimal value)
{
    return value/1.000000000000000000000000000000000m;
}

Reference

Tuple type in C#

It's a rather interesting feature. I first use it the same way as the python tuple type. I immediately found I was wrong. It doesn't support using an index to visit certain element

Stupid enough. I think. Soon I found the correct way, you know, the Item1, Item2 way.

It's so Stupid! Then I found the best way: the named element way.

        Task<(List<string> orderIdList, List<string> orderNoList)> GetExpiringOrderIdListAndOrderNoList(DateTime checkTime);

Ok. It's not very stupid.

PHP array_merge array_diff array_intersect function c# alternative

If you've got LINQ available to you, you can use Union, Except, Intersect, and Distinct:

  • array1.Union(array2).Distinct().ToList()
  • array2.Except(array1)
  • array1.Except(array2)
  • array1.Intersect(array2)

Reference

Superpay 小程序支付后端接口对接记

这两天在和开发小程序的同事对接supay支付,今天总算基本搞完了。他们的文档过于糟糕,太多槽要吐,记录一下也许会帮到其他也需要对接superpay的人。先说说我们的业务流程

  1. 小程序 wx.login 拿到 code
  2. 小程序 wx.getUserInfo 拿到加密的 userData和iv
  3. 小程序登录请求公司后端服务器 /wechatMiniProgram/login 接口三方登录,登录成功拿到可访问公司其他接口的 accessToken
  4. 小程序拿着accessToken下订单
  5. 小程序拿着订单id请求公司后端服务器 /supay/wechatMiniProgramPay/{orderId}
  6. 公司服务器请求 supay 小程序下单接口,获取pay_info 给小程序。故事主要发生在这里。

他们的文档里是有一个流程图的,写成文本大体是下面这样。

  1. 小程序向公司后台服务器发起下单支付请求
  2. 公司后台服务器请求 superpay 服务器获取 openid
  3. superpay 服务器返回 openid 给公司后台服务器
  4. 公司后台服务器拿着openid 请求superpay服务器(小程序下单接口)拿 pay_info
  5. 公司服务器把 pay_info 返回给小程序
  6. 小程序拿 pay_info 发起支付

这个流程图事后看其实也不算错,只是其中第2步和第3步是不必要的。因为小程序在三方登录的时候,我们已经可以拿到openid和unionid。补充一句,小程序支付只需要openid,并不需要unionid。

在和superpay的技术同事沟通过程中,我发现最有价值的聊天记录包括

不要管其他的接口了,就用小程序下单
交易状态 TRADE_FINISHED 不需要处理
小程序下单返回的接口数据中,所有时间均是北京时间
inner_trade_no是 supay 的单号,mch_order_no和outer_trade_no 是你们的单号
trade_amount是人民币金额,虽然例子里写的是纽币
签名的时候字典序是重要的,文档里虽然没有提到,但在签名串字典序末尾追加一个 &key=商户appsecret 再md5是至关重要的。

因为签名需要拼一个query string格式的串,我就想当然的认为是post这个串到supay服务器。这是我的错,这里要以例子为准。例子里写的就是post一个json格式的数据过去。

10.07.2020 补充一个吐槽,小程序返回的 trade_amount 单位并不是人民币,是纽币。而且小程序各接口没有一个能返回人民币实际支付额。我的解决办法是拿自己的订单号调用 superpay 给非小程序支付的查询交易详情接口,这样就能拿到人民币交易金额数据。

.net core System.text.json Serialize & Deserialize

If the field names in your Model class are not exactly the same as in a JSON string, you will need adding an option to guarantee the behavior is what you want. For example, if you have got the following response text:

{"hello":"world"}

and you have a Model class below:

class SampleModel 
{
   public string Hello { get; set; };
}

You can see the property name in your Model class is "Hello" instead of "hello", the following code won't get an expecting result.

SampleModel s = JsonSerializer.Deserialize<SampleModel>("{\"hello\":\"world\"}");

you will get an object like

{
  "Hello": null 
}

You have to use an option below to get it to work.

SampleModel s = JsonSerializer.Deserialize<SampleModel>("{\"hello\":\"world\"}", new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            });

on the other hand, you have to use the following code to guarantee the serialize behavior:

SampleModel s = JsonSerializer.Serialize(new SampleModel() {Hello="world"}, new JsonSerializerOptions
            {
                DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
            });

Thus you get {"Hello":"world"} instead of {"hello":"world"}.

System.text.json sucks.