# GooglePass

## Handle Google Wallet pass state changes

> Webhook endpoint called by Google when a pass is saved to or deleted from a device.\
> \
> \## Supported Event Types\
> \- \*\*save\*\*: Pass added to Google Wallet on a user's device\
> \- \*\*del\*\*: Pass removed from Google Wallet on a user's device\
> \
> \## Security & Verification\
> Google signs all webhook messages using JWT. The system verifies the signature before processing any events.\
> Ensures only authentic messages from Google are acted upon.\
> \
> \## Deduplication\
> Uses the nonce field to prevent duplicate processing of the same event.\
> Already-processed messages are ignored and return 204 No Content.\
> \
> \## Registration Tracking\
> \- Increments/decrements installation count for the pass\
> \- Tracks first installation date when count reaches 1\
> \- Updates aggregate active and total registration statistics

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"GooglePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/google":{"post":{"tags":["GooglePass"],"summary":"Handle Google Wallet pass state changes","description":"Webhook endpoint called by Google when a pass is saved to or deleted from a device.\n\n## Supported Event Types\n- **save**: Pass added to Google Wallet on a user's device\n- **del**: Pass removed from Google Wallet on a user's device\n\n## Security & Verification\nGoogle signs all webhook messages using JWT. The system verifies the signature before processing any events.\nEnsures only authentic messages from Google are acted upon.\n\n## Deduplication\nUses the nonce field to prevent duplicate processing of the same event.\nAlready-processed messages are ignored and return 204 No Content.\n\n## Registration Tracking\n- Increments/decrements installation count for the pass\n- Tracks first installation date when count reaches 1\n- Updates aggregate active and total registration statistics","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Signed message envelope sent by Google.","content":{"application/json":{"schema":{}},"text/json":{"schema":{}},"application/*+json":{"schema":{}}}},"responses":{"200":{"description":"Pass state change processed successfully"},"202":{"description":"Legacy pass format detected (cannot update)"},"204":{"description":"Duplicate event or invalid message ignored"},"404":{"description":"Pass not found by serial number","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Processing error during webhook handling"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```

## Handle DiscoverableProgramMerchantSignupInfo flow redirect

> Webhook endpoint used in Google Wallet's DiscoverableProgramMerchantSignupInfo flow.\
> When users tap "Sign up for more" in Google Wallet, they are redirected to this endpoint.\
> \
> \## User Profile Data\
> Google provides optional user information in Base64-encoded JSON format:\
> \- First and last name\
> \- Address (street, city, zipcode, country)\
> \- Email address\
> \- Phone number\
> \
> \## Parameter Mapping\
> Google's field names (FIRST\_NAME, LAST\_NAME, etc.) are automatically mapped to\
> camelCase tenant-relative parameters (firstName, lastName, etc.) for the signup page.\
> \
> \## Redirect Behavior\
> Combines the provided relative URL with the public tenant URI and redirects the user\
> to the signup page with mapped parameters as query string.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"GooglePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/google/signup":{"get":{"tags":["GooglePass"],"summary":"Handle DiscoverableProgramMerchantSignupInfo flow redirect","description":"Webhook endpoint used in Google Wallet's DiscoverableProgramMerchantSignupInfo flow.\nWhen users tap \"Sign up for more\" in Google Wallet, they are redirected to this endpoint.\n\n## User Profile Data\nGoogle provides optional user information in Base64-encoded JSON format:\n- First and last name\n- Address (street, city, zipcode, country)\n- Email address\n- Phone number\n\n## Parameter Mapping\nGoogle's field names (FIRST_NAME, LAST_NAME, etc.) are automatically mapped to\ncamelCase tenant-relative parameters (firstName, lastName, etc.) for the signup page.\n\n## Redirect Behavior\nCombines the provided relative URL with the public tenant URI and redirects the user\nto the signup page with mapped parameters as query string.","parameters":[{"name":"url","in":"query","description":"Tenant-relative layout path to redirect to.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"userProfile":{"type":"string","description":"Base64-encoded JSON user profile provided by Google."}}},"encoding":{"userProfile":{"style":"form"}}}}},"responses":{"302":{"description":"Redirect to signup page with user data parameters"},"400":{"description":"Invalid Base64 user profile or malformed JSON","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Error during URL construction or decoding"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```

## Handle DiscoverableProgramMerchantSignupInfo flow redirect

> Webhook endpoint used in Google Wallet's DiscoverableProgramMerchantSignupInfo flow.\
> When users tap "Sign up for more" in Google Wallet, they are redirected to this endpoint.\
> \
> \## User Profile Data\
> Google provides optional user information in Base64-encoded JSON format:\
> \- First and last name\
> \- Address (street, city, zipcode, country)\
> \- Email address\
> \- Phone number\
> \
> \## Parameter Mapping\
> Google's field names (FIRST\_NAME, LAST\_NAME, etc.) are automatically mapped to\
> camelCase tenant-relative parameters (firstName, lastName, etc.) for the signup page.\
> \
> \## Redirect Behavior\
> Combines the provided relative URL with the public tenant URI and redirects the user\
> to the signup page with mapped parameters as query string.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"GooglePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/google/signup":{"post":{"tags":["GooglePass"],"summary":"Handle DiscoverableProgramMerchantSignupInfo flow redirect","description":"Webhook endpoint used in Google Wallet's DiscoverableProgramMerchantSignupInfo flow.\nWhen users tap \"Sign up for more\" in Google Wallet, they are redirected to this endpoint.\n\n## User Profile Data\nGoogle provides optional user information in Base64-encoded JSON format:\n- First and last name\n- Address (street, city, zipcode, country)\n- Email address\n- Phone number\n\n## Parameter Mapping\nGoogle's field names (FIRST_NAME, LAST_NAME, etc.) are automatically mapped to\ncamelCase tenant-relative parameters (firstName, lastName, etc.) for the signup page.\n\n## Redirect Behavior\nCombines the provided relative URL with the public tenant URI and redirects the user\nto the signup page with mapped parameters as query string.","parameters":[{"name":"url","in":"query","description":"Tenant-relative layout path to redirect to.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"userProfile":{"type":"string","description":"Base64-encoded JSON user profile provided by Google."}}},"encoding":{"userProfile":{"style":"form"}}}}},"responses":{"302":{"description":"Redirect to signup page with user data parameters"},"400":{"description":"Invalid Base64 user profile or malformed JSON","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Error during URL construction or decoding"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```
