One Time Payment Code Flow

One Time Payment Code (AKA Cash FOP, AKA Reference Number API) guide

Here are some important use cases to consider, as well as the guidelines and APIs needed to implement your cash FOP.

Use cases

There are a number of uses for the Reference Number API. This guide will discuss two use cases and walk you through their implementation.

  • Cash - The user pays in cash at a physical location.
  • VAN - The user transfers money to a Virtual Account Number.

Cash

A user can buy something from Google by paying for it with cash at a physical location, such as a convenience store. To identify the transaction, the user will generate a reference number to take to the store to pay. In addition, Google will display instructions to the user about how to complete the purchase. Ideally as soon as the user completes the purchase, the integrator notifies Google so Google can deliver the product.

Your point of contact at Google will ask for a sample of your typical payment instructions. You’ll work with your Google contact to optimize and refine the messaging.

The user experience Google wants to provide is that the customer order is delivered as they’re leaving the store. Google expects the ReferenceNumberPaidNotification to be received at Google within three minutes of when the customer paid the reference number. Once the ReferenceNumberPaidNotification is sent, the transaction cannot be reversed by the integrator.

VAN

A user can pay for a good with their bank account. Google will request a Virtual Account Number from the integrator, presenting the number and instructions to the user. The user will then copy the number and enter it into their banking application in addition to the amount to transfer.

The integrator needs to verify that the transferred amount matches the referenceNumberGeneration request amount, then notify Google that the reference number has been paid.

Once Google receives the ReferenceNumberPaidNotification, Google will deliver the product and the transaction cannot be reversed by the integrator.

APIs to integrate

The following APIs handle reference number generation and payment notification.

The following APIs handle remittance and settlements.

You will need to integrate all of the above APIs to generate reference numbers and settle with Google.

Generate reference number

Google calls GenerateReferenceNumber when you initiate a purchase. We expect you to respond with a reference number identifying the transaction or account. The expected latency is < 3 seconds.

For Cash transactions, the reference number may be up to 12 characters long.

URL: POST https://[basepath]/refundable-one-time-payment-code-v1/generateReferenceNumber

Request 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"
}

Response JSON

{
  "responseHeader": {
    "responseTimestamp": "1561678947659"
  },
  "result": "SUCCESS",
  "referenceNumber": "38a41c05-ba7b-4040-a909-4331d0b9ce46"
}

Sample Java

`String generateReferenceNumberJson = Utils.decryptAndDecode(encodedEncryptedGenerateReferenceNumberRequest);`
GenerateReferenceNumberRequest request = gson.fromJson(generateReferenceNumberJson, GenerateReferenceNumberRequest.class);

Cancel reference number

Google may choose to cancel a reference number and prevent it from being paid by the user. An example use case is a promotion that has expired. Once you’ve responded with a success to this request, you must ensure that the reference number cannot be paid.

If the user has already initiated the payment process, for example a reference number lookup from the point of sale, your server should respond with a HTTP 423 response and ErrorResponse in the request body with a status of USER_ACTION_IN_PROGRESS.

URL: POST https://[basepath]/refundable-one-time-payment-code-v1/cancelReferenceNumber

Request 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"
}

Response JSON

{
  "responseHeader": {
    "responseTimestamp": "1561680406459"
  },
  "result": "SUCCESS"
}

referenceNumberPaidNotification

Once payment has been accepted and the transaction has been completed, your service needs to notify Google that the transaction is complete and deliver the product to the user. Once this notification is received by Google, Google expects that the transaction is finalized and not reserversable.

referenceNumberPaidNotification endpoint URL:


POST https://vgw.googleapis.com/gsp/one-time-payment-code-v1/referenceNumberPaidNotification/[PIAID]

Request 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"
}

Response JSON

{
  "responseHeader": {
    "responseTimestamp": "1561748642600"
  },
  "result": "SUCCESS"
}

Refund

Google may choose to refund a reference number. Refunds can be made multiple times on a single reference number with refund amounts totalling up to the original payment amount.

Refunds will be initiated by referencing the request ID of the original generateReferenceNumber call, NOT the generated reference number. This is to prevent any issues with reference numbers being reused for other payments.

URL: POST https://[basepath]/refundable-one-time-payment-code-v1/refund

Request JSON

{
  "requestHeader": {
    "protocolVersion": {
      "major": 1,
      "minor": 0,
      "revision": 0
    },
    "requestId": "bWVyY2hhbnQgdHJhbnNhY3Rpb24gaWQ",
    "requestTimestamp": "1502223797000"
  },
  "paymentIntegratorAccountId": "InvisiCashUSA_USD",
  "generateReferenceNumberRequestId": "aW50ZWdyYXRvciB0cmFuc2FjdGlvbiBpZA",
  "currencyCode": "USD",
  "refundAmount": "10000000"
}

Response JSON

{
  "responseHeader": {
    "responseTimestamp": "1481900013178"
  },
  "result": "SUCCESS",
  "paymentIntegratorRefundId": "cmVmdW5kIGlkZW50aWZpZXINCg"
}

Implement remittance

Once you have integrated the APIs for your particular FOP, you are ready for remittance. Remittance works the same across all FOPs.

remittanceStatementNotification

Two days after a transaction, Google will send a remittanceStatementNotification containing a summary of the transactions Google recorded that day. A sample notification looks like this, two days after a transaction:

POST https://www.integratordomain.com/v1/remittanceStatementNotification

Request 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",
  }
}

Notice the totalDueByIntegrator mapping. On this line you can see the net amount the Integrator owes (in micros). Also, the date and type of currency appear in this message, with the billing period representing 00:00:00.000 and 23:59:59.999 of the earliest and latest transaction day(s) respectively.

Reconciliation (remittanceStatementDetails)

For reconciliation, the integrator will call remittanceStatementDetails to get the list of events included in the remittanceStatementNotification.

Google responds to the remittanceStatementDetails request with a paginated list of events. remittanceStatementDetails should be called multiple times if the number of total transactions is greater than 1000. The requests do not need to be made sequentially, and can be parallelized.

Request URL

POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/remittanceStatementDetails

Sample request body

{
  "requestHeader": {
    "protocolVersion": {
      "major": 1,
      "minor": 0,
      "revision": 0
    },
    "requestId": "statement_detail_request_139932019",
    "requestTimestamp": "1502551332087"
  },
  "paymentIntegratorAccountId": "InvisiCashUSA_USD",
  "statementId": "0123434-statement-abc",
  "numberOfEvents": 4
}

Here is a short snippet of a larger response, describing two capture events (transactions).

"captureEvents": [ {
    {
      "eventRequestId": "bWVyY2hhbnQgdHJhbnNhY3Rpb24gaWQ",
      "paymentIntegratorEventId": "ioj32SOIjf23oijSDfoij",
      "eventCharge": "700000000",
      "eventFee": "-28000000"
    },
    {
      "eventRequestId": "Ggghvh78200PQ3Yrpb",
      "paymentIntegratorEventId": "iasdf23dSdfijSDfoij",
      "eventCharge": "800000000",
      "eventFee": "-32000000"
    }
  }

See remittanceStatementDetails to learn more.

acceptRemittanceStatement and acceptRemittanceStatementWithModifications

Integrators should compare these events against the events that they have recorded. If any transactions do not match or transactions are missing, contact Google for further investigation. If all transactions match, and the process fee does not include taxes, call acceptRemittanceStatement. If taxes are inclusive, call acceptRemittanceStatementWithModifications.

The acceptRemittanceStatement method is used when there are no taxes on fees.

If a tax is to be included, call acceptRemittanceStatementWithModifications and define the tax rate. If your tax rate changes, make sure this is updated. After a successful acceptRemittanceStatement, initiate your bank transfer to the Google account.

Request URL for acceptRemittanceStatement

POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/acceptRemittanceStatement

Sample request body

{
  "requestHeader": {
    "protocolVersion": {
      "major": 1,
      "minor": 0,
      "revision": 0
    },
    "requestId": "0123434-abc",
    "requestTimestamp": "1502545413098"
  },
  "paymentIntegratorAccountId": "InvisiCashUSA_USD",
  "statementId": "0123434-statement-abc"
}

Sample response

{
  "responseHeader": {
    "responseTimestamp": "1519996752221"
  }
  "acceptRemittanceStatementResultCode": "SUCCESS"
}

Request URL for acceptRemittanceStatementWithModifications

POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/acceptRemittanceStatementWithModifications

Sample request body

{
  "requestHeader": {
    "protocolVersion": {
      "major": 1,
      "minor": 0,
      "revision": 0
    },
    "requestId": "0123434-abc",
    "requestTimestamp": "1502545413098"
  },
  "paymentIntegratorAccountId": "InvisiCashUSA_USD",
  "statementId": "0123434-statement-abc"
  "feeToVatModification": {
    "vatToFeeRatioInMicros": "150000"
  }
}

Sample response

{
  "responseHeader": {
    "responseTimestamp": "1519996752221"
  }
  "acceptRemittanceStatementWithModificationsResultCode": "SUCCESS"
}