下面是一些需要考虑的重要用例,以及实现现金 FOP 所需的准则和 API。
用例
Reference Number API 有多种用途。本指南将讨论两个用例,并逐步引导您完成其实现过程。
现金
用户可以在实体店(例如便利店)使用现金付款来从 Google 购买商品。为了识别交易,用户将生成一个参考号,以便在实体店付款。此外,Google 还会向用户显示有关如何完成购买交易的说明。理想情况下,只要用户完成购买,集成商即可通知 Google,以便 Google 提供相应产品。
您的 Google 联系人会要求您提供典型付款说明的示例。您将与 Google 联系人合作,优化和完善宣传信息。
Google 希望提供的用户体验,即客户所订商品在客户离开商店时送达。Google 预计在客户支付参考号之后的三分钟内,Google 会收到 ReferenceNumberPaidNotification。ReferenceNumberpaidNotification 发送后,集成商将无法撤销该交易。
VAN
用户可以使用自己的银行账户支付商品费用。Google 会要求集成商提供一个虚拟账号,并向用户显示号码和说明。用户需要复制该号码,并将其与要转出的金额一起输入到银行应用程序中。
集成商需要验证转移的金额是否与 referenceNumberGeneration 请求金额一致,然后通知 Google 该参考编号已支付。
一旦 Google 收到 ReferenceNumberPaidNotification,Google 将交付商品,并且集成商无法撤销交易。
在您的服务器和 Google 服务器之间发送消息
在您的服务器和 Google 服务器之间发送消息时(或者反过来),请遵守以下准则。
传入请求 - DecryptWithVendorPrivateKey(Base64UrlDecode(request))
外发回复 - Base64UrlEncode(EncryptWithGooglePublicKey(request))
Google 请求 - Base64UrlEncode(EncryptWithGooglePublicKey(request))
Google 回复 - DecryptWithVendorPrivateKey(Base64UrlDecode(request))
此处提供了一个 Java 语言的 PGP 库和示例,其中展示了如何处理请求和响应。
遵循幂等行为
幂等性是指您不应尝试重新处理已经成功处理的任何请求(例如付款)。应改为报告处理成功后的响应。
重要意义
Google 可能会重试某些请求,以确保我们这边的状态与供应商那边的状态相同。您的系统不应认为这是另一项交易。因此,幂等性非常重要。这意味着集成商不应重新处理已经成功处理的内容。在这种情况下,应改为发送先前的响应。
如何实现幂等性
如果 Google 发送重试请求,那么请求 ID 是相同的,内容相同,但时间戳会不同。使用您之前发送的同一回复进行回复。如果您的第一个响应是 200(成功),那么 Google 会得到相同的响应,但时间戳不同。
如果您以前的响应为错误(400 或 500 等),则应将该请求作为新请求进行处理,并再次检查。如果您的服务器首次出现故障,这会非常有用,并且重试该请求会让请求再次得到成功处理。
如需了解详情,请参阅此详细指南。
使用付款集成商帐号 ID (PIAID)
与 Google 的集成可能需要与 Google 的不同业务实体集成。例如,Google Play 是一个实体,另一个实体是 YouTube,另一个实体是 Google Ads。这些配置涉及不同的商家帐号,分别用来代表每种配置。
对于从 Google 中的每个实体到每个商家帐号的映射,Google 会提供付款集成商帐号 ID (PIAID)。如需查看现金 FOP API 的示例,请参阅 generateReferenceNumber。以下是使用此映射的示例。
对于从 Google 中的每个实体到每个商家帐号的映射,Google 会提供付款集成商帐号 ID (PIAID)。如需查看使用 Cash FOP API 的示例,请参阅 generateReferenceNumber。以下是使用此映射的示例。
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "bWVyY2hhbnQgdHJhbnNhY3Rpb24gaWQ",
"requestTimestamp": "1502220196077"
},
"paymentIntegratorAccountId": "InvisiCashUSA_USD",
"transactionDescription": "Google - Music",
"currencyCode": "USD",
"amount": "2000000"
}
请注意突出显示的部分。此处所需的两个值是您在 Google 的联系人提供的 paymentIntegratorAccountId
和您的商家帐号。
根据提供服务的每个国家/地区,集成商可能也会拥有不同的帐号。这可能是由于各个国家/地区的税法不同以及不同国家/地区之间的其他差异造成的。在这种情况下,可能会为每个国家/地区生成另一个 PIAID。
要集成的 API
以下 API 用于处理参考号的生成和付款通知。
以下 API 用于处理汇款和结算。
- RemittanceStatementNotification
- RemittanceStatementDetails
- AcceptRemittanceStatement/AcceptRemittanceStatement(已修改)
您需要集成上述所有 API 才能生成参考编号并与 Google 达成结算。
生成参考号
当您发起购买交易时,Google 会调用 GenerateReferenceNumber 方法。我们希望您能在回复中提供用于标识相应交易或帐号的参考编号。预期延迟时间小于 3 秒。
对于现金交易,参考编号最长可达 12 个字符。
网址:POST https://[your basepath]/v1/generateReferenceNumber
请求 JSON
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "cf9fde73-3735-4463-8e6e-c999fda35af6",
"requestTimestamp": "1561678470395"
},
"paymentIntegratorAccountId": "Sample_Cash_Vendor_282",
"transactionDescription": "Google Play - Tester",
"currencyCode": "USD",
"amount": "10000000"
}
响应 JSON
{
"responseHeader": {
"responseTimestamp": "1561678947659"
},
"result": "SUCCESS",
"referenceNumber": "38a41c05-ba7b-4040-a909-4331d0b9ce46"
}
Java 示例
`String generateReferenceNumberJson = Utils.decryptAndDecode(encodedEncryptedGenerateReferenceNumberRequest);`
GenerateReferenceNumberRequest request = gson.fromJson(generateReferenceNumberJson, GenerateReferenceNumberRequest.class);
取消参考号
Google 可能会选择取消某个参考号,并阻止用户向其付款。例如,促销已过期。成功对此请求做出回复后,您必须确保无法支付参考号。
如果用户已启动付款流程(例如在销售终端查找参考号),您的服务器应返回 HTTP 423 响应,并在请求正文中包含 USER_ACTION_IN_PROGRESS 状态的 ErrorResponse。
网址:POST https://[your basepath]/v1/cancelReferenceNumber
请求 JSON
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "51e00f16-36ba-4490-b228-0a670d202206",
"requestTimestamp": "1561678947926"
},
"paymentIntegratorAccountId": "Sample_Cash_Vendor_282",
"referenceNumber": "38a41c05-ba7b-4040-a909-4331d0b9ce46"
}
响应 JSON
{
"responseHeader": {
"responseTimestamp": "1561680406459"
},
"result": "SUCCESS"
}
referenceNumberPaidNotification
开发者接受付款且交易完成后,您的服务需要通知 Google 交易已完成,并将商品交付给用户。Google 收到此通知后,希望交易已敲定,无法预留。
referenceNumberPaidNotification 端点网址:
POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/referenceNumberPaidNotification/[PIAID]
请求 JSON
{
"requestHeader": {
"requestTimestamp": "1561748625577",
"requestId": "ae8e310a-92de-436a-a32c-0bd753ae4e4b",
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
}
},
"paymentIntegratorTransactionId": "cf9fde73-3735-4463-8e6e-c999fda35af6",
"referenceNumber": "e4e15b5d-8154-4068-b6eb-560e2a65ac48",
"paymentLocation": {
"brandName": "TestMart",
"locationId": "1234"
},
"paymentIntegratorAccountId": "Sample_Cash_Vendor_282",
"paymentTimestamp": "1561748625577"
}
响应 JSON
{
"responseHeader": {
"responseTimestamp": "1561748642600"
},
"result": "SUCCESS"
}
实现汇款
为您的特定 FOP 集成 API 后,您就可以进行汇款了。所有付款方式的汇款方式都是一样的。
remittanceStatementNotification
在交易发生两天后,Google 会发送一条 remittanceStatementNotification,其中包含 Google 当天记录的交易的摘要。交易两天后,示例通知如下所示:
POST https://www.integratordomain.com/v1/remittanceStatementNotification
请求 JSON
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "0123434-statement-abc",
"requestTimestamp": "1502632800000"
},
"paymentIntegratorAccountId": "InvisiCashUSA_USD",
"remittanceStatementSummary": {
"statementDate": "1502607600000",
"billingPeriod": {
"startDate": "1502434800000",
"endDate": "1502521199000",
},
"dateDue": "1503212400000",
"currencyCode": "INR",
"totalDueByIntegrator": "1076000000",
}
}
请注意 totalDueByIntegrator
映射。在该行,您可以看到集成商欠付的净金额(以微单位表示)。此外,消息中还显示了货币的日期和类型,结算周期分别为最早和最近交易日的 00:00:00.000 和 23:59:59.999。
对账 (remittanceStatementDetails
)
对于对帐,集成商将调用 remittanceStatementDetails 以获取 remittanceStatementNotification 中包含的事件列表。
Google 使用分页的事件列表响应 remittanceStatementDetails
请求。如果总交易次数大于 1000,则应多次调用 remittanceStatementDetails
。这些请求不需要依序发出,并且可以并行处理。
请求网址
POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/remittanceStatementDetails
请求正文示例
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "statement_detail_request_139932019",
"requestTimestamp": "1502551332087"
},
"paymentIntegratorAccountId": "InvisiCashUSA_USD",
"statementId": "0123434-statement-abc",
"numberOfEvents": 4
}
以下是一个较长响应的一小段代码,描述了两个捕获事件(事务)。
"captureEvents": [ {
{
"eventRequestId": "bWVyY2hhbnQgdHJhbnNhY3Rpb24gaWQ",
"paymentIntegratorEventId": "ioj32SOIjf23oijSDfoij",
"eventCharge": "700000000",
"eventFee": "-28000000"
},
{
"eventRequestId": "Ggghvh78200PQ3Yrpb",
"paymentIntegratorEventId": "iasdf23dSdfijSDfoij",
"eventCharge": "800000000",
"eventFee": "-32000000"
}
}
如需了解详情,请参阅 remittanceStatementDetails
。
acceptRemittanceStatement
和acceptRemittanceStatementWithModifications
集成商应将这些事件与其记录的事件进行比较。如有任何交易不相符或交易丢失,请与 Google 联系,做进一步调查。如果所有交易均相符,并且手续费不含税费,请调用 acceptRemittanceStatement
。如果包含税费,则调用 acceptRemittanceStatementWithModifications
。
如果没有其他费用税费,请使用 acceptRemittanceStatement
方法。
如果要包含税费,请调用 acceptRemittanceStatementWithModifications
并定义税率。如果您的税率发生变化,请务必进行更新。acceptRemittanceStatement
成功后,开始向 Google 账号进行银行转账。
acceptRemittanceStatement
的请求网址
POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/acceptRemittanceStatement
请求正文示例
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "0123434-abc",
"requestTimestamp": "1502545413098"
},
"paymentIntegratorAccountId": "InvisiCashUSA_USD",
"statementId": "0123434-statement-abc"
}
响应示例
{
"responseHeader": {
"responseTimestamp": "1519996752221"
}
"acceptRemittanceStatementResultCode": "SUCCESS"
}
acceptRemittanceStatementWithModifications
的请求网址
POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/acceptRemittanceStatementWithModifications
请求正文示例
{
"requestHeader": {
"protocolVersion": {
"major": 1,
"minor": 0,
"revision": 0
},
"requestId": "0123434-abc",
"requestTimestamp": "1502545413098"
},
"paymentIntegratorAccountId": "InvisiCashUSA_USD",
"statementId": "0123434-statement-abc"
"feeToVatModification": {
"vatToFeeRatioInMicros": "150000"
}
}
响应示例
{
"responseHeader": {
"responseTimestamp": "1519996752221"
}
"acceptRemittanceStatementWithModificationsResultCode": "SUCCESS"
}