会员卡。 用于ASP.NET中通行证的Google Pay API

借助Apple Wallet和Google Pay,银行卡存储应用程序迅速进入了我们的生活。 除了银行业务,这两个平台还允许您使用其他类型的卡-会员卡,礼品卡,活动门票,登机牌等。




在一家为一个庞大零售网络提供服务的公司工作期间,我不得不将该网络的会员卡集成到Apple Wallet和Google Pay中。 而且,如果您只是因为集成层具有多功能性而不得不修改Apple Wallet,那么在Google Pay的帮助下,大部分精力和精力都花在了弄清楚文档,找到合适的工具和开发概念的第一个证明上。 尽管总体上其余工作的速度比Apple Wallet快得多,但我花了一天的时间弄清楚如何启动该服务,因此我不介意有人在我之前写过类似的文章。

1.物资


会员卡使用两个实体表示-会员类别和会员对象。

  • 会员类别是所有会员卡的一种模板。 它包含所有地图通用的字段,例如字体颜色,指向图标资源,背景,文本字段的链接等,可以在此处找到完整说明: Loyaltyclass
  • 忠诚度对象 -LoyaltyClass的实例。 它还包含特定客户的特定卡的数据-卡号,名称,其他文本字段。 此处描述: 忠诚对象

为了接收卡,用户必须遵循格式链接
www.android.com/payapp/savetoandroidpay / {JWT} ,其中JWT是一个令牌,其中包含带有LoyaltyClass数据的JSON。 但是,由于URL的长度有限制,因此,如果其结构包含许多字符,建议您首先创建一个忠诚度类。

如果由于模板,样式,添加或更改文本字段的更改而需要更新地图,则可以使用API​​进行。 只需使用新版本的地图来满足POST请求,Google服务本身就会同步拥有该地图的用户的所有应用程序。


2.工具和文档


问题在于, Google Pay Pass for Passes文档中的所有示例都是专门针对Java,PHP和Python的,文档本身强烈建议“使用客户端库来简化使用该API的过程”。


遵循这个建议,我很高兴地去找nuget,但是Google Pay的资料库不存在。 Glory to Brin,Google中第一行“ Google pays for pass dotnet”返回了Google Pay API for Passes实用程序库页面,该页面找到了我所需的内容,尽管是ZIP存档格式,其中有一个.net项目,生成的类,该类是Google Pay API- Passes客户端库的Google Pay API的包装。


从项目中是否存在Google.Apis.Walletobjects.v1.1.9.2.00.nuspec文件来看,部署nuget包仍然是Google团队计划的一部分。 打开该文件以查找文档后,我没有发现任何具体的内容,并且描述部分中的某些链接完全发送到了不存在的页面。

3.获取访问令牌


要直接开始使用Google Pay API for Passes,您需要获取访问令牌,为此,您需要:

  1. 有一个Google Merchant帐户,您可以在这里获得
  2. 创建一个服务帐户,获取一个带有凭证的文件-一个带有服务帐户详细信息的json文档,包括标识符,电子邮件,私钥等。 如文档所建议,您需要将此文件存储在安全的地方。
  3. 在Google Merchant Center链接商家帐户和服务帐户

使用此文件,您可以使用Google.Apis.Auth.OAuth2库登录:

private await Task<string> GetOAuthToken() {         string serviceAccountFile = string.Empty;         serviceAccountFile = ConfigurationManager.AppSettings["GooglePayServiceAccountConfigPath"];        /*              Credential, GoogleCredential              Service Account,   ,      scopes API,             */         var credential = GoogleCredential.FromFile(serviceAccountFile)                            .CreateScoped(WalletobjectsService.Scope.WalletObjectIssuer);        /*        Access token        ,   GetAccessTokenForRequestAsync         ,               */         var token = async credential.UnderlyingCredential.GetAccessTokenForRequestAsync();         return token; } 

4.创建地图


为了创建会员卡,您必须首先创建会员等级。 可以使用API​​和Google Merchant Center网络界面来创建忠诚度等级。 请注意类别名称,因为该名称在Google Pay基础架构中必须唯一。

创建忠诚度类别后,您可以创建忠诚度对象。 为此,您将需要我们之前添加到项目中的库:创建一个请求对象,指定OAuth令牌,转移创建的LoyaltyObject对象,然后执行请求:

 public GooglePayApiService() { // ,    Merchant Account IssuerId = ConfigurationManager.AppSettings["GooglePayIssuerId"]; _wobService = new WalletobjectsService(); } private async Task<LoyaltyObject> ConvertLoyaltyObjectFromTemplate(GooglePayPassTemplate template) { string id = $"{IssuerId}.{template.SerialNumber}"; string loyaltyClassName = ConfigurationManager.AppSettings["GooglePayStoreCardClassName"];     var loyaltyClass = await GetLoyaltyClass(loyaltyClassName); var result =  new LoyaltyObject { Id = id, AccountName = template.AccountName,          Barcode = new Barcode          {          AlternateText = template.BarcodeText,               Value = template.SerialNumber,               Type = "pdf417"          },          Kind = "walletObject#loyaltyObject",          ClassId = loyaltyClass.Id,          ClassReference = loyaltyClass,          State = "active"     };     return result; } private async Task<LoyaltyObject> CreateLoyaltyObject(LoyaltyObject loyaltyObject) { var saveRequest = _wobService.Loyaltyobject.Insert(loyaltyObject); saveRequest.OauthToken = await GetOAuthToken(); var savedObject = await saveRequest.ExecuteAsync(); return savedObject; } 

此示例中的GooglePayPassTemplate是DTO,用于存储用户的地图模板,该模板由单独的开发服务生成。

5.地图更新


此处的原理与创建时的原理相同:我们生成一个请求,传输更新的LoyaltyObject对象,然后执行:

 private async Task<LoyaltyObject> UpdateLoyaltyObject(LoyaltyObject loyaltyObject) { var updateRequest = _wobService.Loyaltyobject.Update(loyaltyObject, loyaltyObject.Id);           updateRequest.OauthToken = await GetOAuthToken(); var savedObject = await updateRequest.ExecuteAsync(); return savedObject; } 

完成请求后,如果设备在网络上并且具有Internet连接,则安装了卡的用户的应用程序中的卡将在几秒钟后更新。



6. JWT一代


要安装卡,您必须将用户重定向到www.android.com/payapp/savetoandroidpay / {JWT}链接。 可以在此链接上找到令牌结构的描述。


令牌由RSA-SHA256签名,签名可以使用带有服务帐户凭据的同一文件生成:

 public static class JwtHelper { public static string CreateJwtForLoyaltyObject(LoyaltyObject loyaltyObject) { /*       credential   ,         */ ServiceAccountCredential credential; var now = DateTime.UtcNow; DateTime unixEpoch = new DateTime(1970, 01, 01); // 1970-01-01 00:00:00 UTC var secondsSinceEpoch = (int)Math.Round((now - unixEpoch).TotalSeconds); string serviceAccountFile = serviceAccountFile = ConfigurationManager.AppSettings["GooglePayServiceAccountConfigPath"]; using (var fs = new FileStream(serviceAccountFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { credential = ServiceAccountCredential.FromServiceAccountData(fs); } /*    JwtPayload,     payload-a  JWT */ var jwtPayload = new JwtPayload { iat = secondsSinceEpoch, iss = credential.Id, payload = new JwtInternalPayload { loyaltyObjects = new[] { new LoyaltyObjectPayload { id = loyaltyObject.Id } } } }; string header = @"{""alg"":""RS256"",""typ"":""JWT""}"; string payload = JsonConverter.SerializeObject(jwtPayload); string base64Header = EscapedBase64(Convert.ToBase64String(Encoding.UTF8.GetBytes(header))); string base64Payload = EscapedBase64(Convert.ToBase64String(Encoding.UTF8.GetBytes(payload))); //        Signature string signature = EscapedBase64(credential.CreateSignature( Encoding.UTF8.GetBytes($"{base64Header}.{base64Payload}") )); var token = $"{base64Header}.{base64Payload}.{signature}"; return token; } private static string EscapedBase64(string base64) { return base64.Replace('+', '-') .Replace('/', '_') .Replace("=", ""); } } 

结论


在本文中,我们介绍了使用Google Pay Pass for Passes的基础知识:设置帐户,连接到该API,创建忠诚度类别和忠诚度对象。

如果UFO赞成,我将分别向您介绍如何使用Apple Wallet(在实施方面,所有工作都比较困难),如何通过一项Web服务使Apple Wallet与Google Pay成为朋友,而不感到痛苦。


有用的链接


Source: https://habr.com/ru/post/zh-CN434486/


All Articles