Przewodnik po metodzie płatności gotówkowej (ang. Cash Number API)

Oto kilka ważnych przypadków użycia, które warto wziąć pod uwagę, a także wytyczne i interfejsy API niezbędne do wdrożenia formy płatności gotówkowej.

Przypadki użycia

Interfejs Reference Number API ma wiele zastosowań. W tym przewodniku omawiamy 2 przypadki użycia i pokazujemy, jak przebiega ich implementacja.

  • Gotówka – użytkownik płaci gotówką w sklepie stacjonarnym.
  • VAN – użytkownik przesyła pieniądze na numer konta wirtualnego (VAN).

Gotówka

Użytkownik może kupić coś od Google, płacąc za to gotówką w sklepie stacjonarnym, na przykład w sklepie wielobranżowym. Aby zidentyfikować transakcję, użytkownik generuje numer referencyjny, który należy zabrać do sklepu. Dodatkowo Google wyświetli użytkownikowi instrukcje dotyczące sfinalizowania zakupu. W idealnej sytuacji zaraz po sfinalizowaniu zakupu przez użytkownika integrator powiadamia Google, aby umożliwić nam dostarczenie produktu.

Osoba kontaktowa w Google poprosi o próbki typowych instrukcji płatności. Będziesz współpracować ze swoją osobą kontaktową w Google, aby zoptymalizować i dopracować przekaz.

Z myślą o użytkownikach Google chce zapewnić, że zamówienie klienta jest dostarczane w momencie, gdy ten wychodzi ze sklepu. Firma Google oczekuje, że numer ReferenceNumberPaidNotification zostanie przesłany do Google w ciągu 3 minut od dokonania płatności przez klienta za numer referencyjny. Integrator nie może cofnąć transakcji, gdy zostanie wysłany ReferenceNumberpaidnotification.

VAN

Użytkownik może zapłacić za towar za pomocą konta bankowego. Google poprosi integratora o numer konta wirtualnego (VAN), który przedstawia ten numer oraz instrukcje użytkownikowi. Następnie użytkownik skopiuje ten numer i wpisze go w aplikacji bankowej oprócz kwoty do przelewu.

Integrator musi sprawdzić, czy przenoszona kwota jest zgodna z kwotą żądania referencyjnegoNumberGeneration, a następnie powiadomić Google o zapłaceniu numeru referencyjnego.

Gdy Google otrzyma powiadomienie ReferenceNumberPaidNotification, dostarczy usługę. Integratora nie będzie mógł cofnąć transakcji.

wysyłanie wiadomości między Twoimi serwerami a serwerami Google;

Podczas wysyłania wiadomości między swoimi serwerami a serwerami Google lub odwrotnie, postępuj zgodnie z tymi wskazówkami.

Prośba przychodzącaDecryptWithVendorPrivateKey(Base64UrlDecode(request))

Odpowiedź wychodzącaBase64UrlEncode(EncryptWithGooglePublicKey(request))

Prośba do GoogleBase64UrlEncode(EncryptWithGooglePublicKey(request))

Odpowiedź GoogleDecryptWithVendorPrivateKey(Base64UrlDecode(request))

Oto biblioteka PGP i przykład w języku Java, które pokazują obsługę żądań i odpowiedzi.

Postępuj zgodnie z zachowaniem idempotentnym

Idempotentność oznacza, że nie należy podejmować prób ponownego przetwarzania żadnych żądań (np. płatności), które zostały już przetworzone. Zamiast tego należy zgłosić odpowiedź dotyczącą udanego przetwarzania.

Dlaczego to ważne

Google może ponowić próbę przesłania niektórych próśb, aby sprawdzić, czy stan po naszej stronie jest taki sam jak po stronie dostawcy. System nie powinien sądzić, że jest to inna transakcja. Dlatego idempotentność jest tak ważna. Oznacza to, że integrator nie powinien ponownie przetwarzać czegoś, co zostało już przetworzone. W takim przypadku powinna zostać wysłana poprzednia odpowiedź.

Jak wdrożyć idempotentność

Jeśli Google spróbuje ponownie, identyfikator żądania będzie taki sam, treść też będzie taka sama, ale sygnatura czasowa będzie inna. Wyślij w odpowiedzi tę samą odpowiedź, która została przez Ciebie wcześniej wysłana. Jeśli pierwsza odpowiedź to 200 (Sukces), Google spodziewa się tej samej odpowiedzi z inną sygnaturą czasową.

Jeśli poprzednia odpowiedź zawierała błąd (400 lub 500 itd.), przetwórz tę prośbę jako nową prośbę i sprawdź ją jeszcze raz. Jest to przydatne, jeśli serwer za pierwszym razem był niedostępny. Jeśli spróbujesz ponownie przetworzyć żądanie, będzie to miało szansę na pomyślne przetworzenie.

Więcej informacji znajdziesz w tym szczegółowym przewodniku.

Używanie identyfikatora konta integratora płatności (PIAID)

Integracja z Google może wymagać integracji z różnymi podmiotami biznesowymi Google. Na przykład Google Play to jeden podmiot, drugi to YouTube, a jeszcze Google Ads. Te konfiguracje wymagają różnych kont sprzedawców, które będą reprezentować każdą z tych konfiguracji.

W celu zmapowania każdego podmiotu w Google na każde konto sprzedawcy Google udostępnia identyfikatory kont integratora płatności (PIAID). Przykład interfejsu API FOP za gotówkę znajdziesz w rekomendacji generateReferenceNumber. Oto przykład, który korzysta z tego mapowania.

W celu zmapowania każdego podmiotu w Google na każde konto sprzedawcy Google udostępnia identyfikatory kont integratora płatności (PIAID). Przykład użycia interfejsu API FOP za pomocą gotówki znajdziesz w artykule generateReferenceNumber. Oto przykład, który korzysta z tego mapowania.


{
  "requestHeader": {
    "protocolVersion": {
      "major": 1,
      "minor": 0,
      "revision": 0
    },
    "requestId": "bWVyY2hhbnQgdHJhbnNhY3Rpb24gaWQ",
    "requestTimestamp": "1502220196077"
  },
  "paymentIntegratorAccountId": "InvisiCashUSA_USD",
  "transactionDescription": "Google - Music",
  "currencyCode": "USD",
  "amount": "2000000"
}

Zwróć uwagę na zaznaczony fragment. Wymagane są 2 wartości: paymentIntegratorAccountId podane przez osobę kontaktową w Google oraz Twoje konto sprzedawcy.

Integrator może też mieć różne konta w zależności od obsługiwanego kraju. Wynika to z różnych przepisów podatkowych i innych różnic w poszczególnych krajach. W takim przypadku dla każdego kraju może zostać wygenerowany kolejny identyfikator PIAID.

Interfejsy API do integracji

Poniższe interfejsy API obsługują generowanie numerów referencyjnych i powiadomienia o płatnościach.

Przelewy i rozliczenia obsługują wymienione poniżej interfejsy API.

Aby generować numery referencyjne i rozliczać się z Google, musisz zintegrować wszystkie powyższe interfejsy API.

Wygeneruj numer referencyjny

Google wywołuje GenerateReferenceNumber, gdy inicjujesz zakup. W odpowiedzi prześlemy Ci numer referencyjny umożliwiający identyfikację transakcji lub konta. Oczekiwany czas oczekiwania wynosi < 3 sekundy.

W przypadku transakcji gotówką numer referencyjny może mieć maksymalnie 12 znaków.

Adres URL: POST https://[your basepath]/v1/generateReferenceNumber

Żądanie 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"
}

Plik JSON odpowiedzi

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

Przykładowa Javy

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

Anuluj numer referencyjny

Google może anulować numer referencyjny i uniemożliwić użytkownikowi jego zapłatę. Przykładem może być promocja, która wygasła. Po pomyślnym przesłaniu prośby upewnij się, że nie można opłacić numeru referencyjnego.

Jeśli użytkownik zainicjował już proces płatności (np. wyszukanie numeru referencyjnego w punkcie sprzedaży), serwer powinien przesłać odpowiedź HTTP 423, a w treści żądania błąd ErrorResponse, stan USER_ACTION_IN_PROGRESS.

Adres URL: POST https://[your basepath]/v1/cancelReferenceNumber

Żądanie 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"
}

Plik JSON odpowiedzi

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

referenceNumberPaidNotification

Po zaakceptowaniu płatności i zrealizowaniu transakcji usługa musi powiadomić Google o zakończeniu transakcji i dostarczyć produkt użytkownikowi. Po otrzymaniu tego powiadomienia Google oczekuje, że transakcja zostanie sfinalizowana i nie będzie można jej zarezerwować.

Adres URL punktu końcowego referenceNumberPaidNotification:


POST https://billpaynotification.googleapis.com/secure-serving/gsp/v1/referenceNumberPaidNotification/[PIAID]

Żądanie 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"
}

Plik JSON odpowiedzi

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

Wdrożenie przelewu

Po zintegrowaniu interfejsów API dla konkretnej formy płatności możesz zacząć realizować przelew. Przelew działa tak samo w przypadku wszystkich form płatności.

remittanceStatementNotification

Dwa dni od dokonania transakcji Google wyśle powiadomienie remittanceStatementNotification zawierające podsumowanie transakcji zarejestrowanych w danym dniu. Przykładowe powiadomienie wygląda tak 2 dni po dokonaniu transakcji:

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

Żądanie 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",
  }
}

Zwróć uwagę na mapowanie totalDueByIntegrator. W tym wierszu podana jest kwota netto, którą integrator musi zapłacić (w mikro). W komunikacie pojawią się też data i typ waluty, przy czym okres rozliczeniowy to odpowiednio 00:00:00.000 i 23:59:59.999 najwcześniejszego i ostatniego dnia transakcji.

Uzgadnianie (remittanceStatementDetails)

Na potrzeby uzgodnienia integrator wywołuje remittanceStatementDetails, aby pobrać listę zdarzeń uwzględnionych w powiadomieniu remittanceStatement Notification.

W odpowiedzi na żądanie remittanceStatementDetails Google udostępnia dzieloną na strony listę zdarzeń. Funkcja remittanceStatementDetails powinna zostać wywołana kilka razy, jeśli łączna liczba transakcji przekracza 1000. Żądania nie muszą być wysyłane po kolei i mogą być równoległe.

Adres URL żądania

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

Przykładowa treść żądania

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

Oto krótki fragment dłuższej odpowiedzi opisujący 2 zdarzenia przechwytywania (transakcje).

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

Więcej informacji: remittanceStatementDetails.

acceptRemittanceStatementacceptRemittanceStatementWithModifications

Integrator powinien porównać te zdarzenia ze zdarzeniami, które zarejestrowały. Jeśli transakcje nie są zgodne lub brakuje transakcji, skontaktuj się z Google, aby dokładniej zbadać problem. Jeśli wszystkie transakcje są zgodne, a opłata transakcyjna nie obejmuje podatków, wywołaj acceptRemittanceStatement. Jeśli podatki obejmują podatki, zadzwoń pod numer acceptRemittanceStatementWithModifications.

Metoda acceptRemittanceStatement jest używana, gdy opłaty nie są opodatkowane.

Jeśli chcesz uwzględnić podatek, zadzwoń pod numer acceptRemittanceStatementWithModifications i podaj stawkę podatku. Jeśli Twoja stawka podatku ulegnie zmianie, zaktualizuj ją. Gdy acceptRemittanceStatement zostanie zrealizowana, prześlij przelew na konto Google.

URL żądania dla acceptRemittanceStatement

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

Przykładowa treść żądania

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

Przykładowa odpowiedź

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

URL żądania dla acceptRemittanceStatementWithModifications

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

Przykładowa treść żądania

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

Przykładowa odpowiedź

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