{
  "swagger": "2.0",
  "info": {
    "title": "Google Standard Payments Google Hosted VirtualCards API",
    "description": "This includes services hosted by Google for Virtual Cards.",
    "version": "v1"
  },
  "host": "vgw.googleapis.com",
  "basePath": "/gsp",
  "schemes": ["https"],
  "paths": {
    "/virtual-cards-v1/transactionEventNotification": {
      "post": {
        "tags": ["vgw"],
        "operationId": "TransactionEventNotification",
        "description": "Notify Google of transaction event that has occurred for an enrollment in {{product_name_short}}. An example request looks like: { \"requestHeader\": { \"protocolVersion\": { \"major\": 1 }, \"requestId\": \"BKD0GF23KSD8S23\", \"requestTimestamp\": { \"epochMillis\": \"1481899949606\" }, \"paymentIntegratorAccountId\": \"abcdef123456\" }, \"enrollmentRequestId\": \"G1MQ0YERJ0Q7LPM\", \"transactionUpdateAvailable\": {}, \"timestamp\": { \"epochMillis\": \"1481899900000\" } } An example response looks like: { \"responseHeader\": { \"responseTimestamp\": { \"epochMillis\": \"1481899950236\" } }, \"result\": { \"success\" : {} } } ",
        "parameters": [
          {
            "name": "body",
            "description": "The request body.",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/TransactionEventNotificationRequest"
            }
          }
        ],
        "responses": {
          "default": {
            "description": "Successful operation",
            "schema": {
              "$ref": "#/definitions/TransactionEventNotificationResponse"
            }
          }
        }
      }
    },
    "/virtual-cards-v1/echo": {
      "post": {
        "tags": ["vgw"],
        "operationId": "Echo",
        "description": "Echos back a string sent from the client. If the echo is successful, the endpoint will return an HTTP 200 and the response will be of type `EchoResponse`. If the endpoint encounters an error while processing the request, the endpoint will return HTTP 4xx or 5xx and the HTTP body will either be of type `ErrorResponse` or contain a generic error (e.g. a message similar to \"There was an error. Please try again later.\"). The generic error is used in situations where an `ErrorResponse` with a clear description could be used to help an attacker understand the payment integrator account identifier of other integrators. In these situations, where either the signing key doesn't match, the payment integrator identifier was not found, or the encryption key was unknown, this method will return a generic error. If the request signature could be verified, additional information regarding the error will be returned in an `ErrorResponse`. An example request looks like: { \"requestHeader\": { \"protocolVersion\": { \"major\": 1 }, \"requestId\": \"G1MQ0YERJ0Q7LPM\", \"requestTimestamp\": { \"epochMillis\": \"1481899949606\" }, \"paymentIntegratorAccountId\": \"InvisiCashUSA_USD\" }, \"clientMessage\": \"Client echo message\" } An example success response looks like: { \"responseHeader\": { \"responseTimestamp\": { \"epochMillis\":\"1481899950236\" } }, \"clientMessage\": \"Client echo message\", \"serverMessage\": \"Debug ID 12345\" } ",
        "parameters": [
          {
            "name": "body",
            "description": "The request body.",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/EchoRequest"
            }
          }
        ],
        "responses": {
          "default": {
            "description": "Successful operation",
            "schema": {
              "$ref": "#/definitions/EchoResponse"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "TransactionEventNotificationRequest": {
      "description": "Request for the `transactionEventNotification` method.",
      "type": "object",
      "properties": {
        "requestHeader": {
          "description": "**REQUIRED**: Common header for all requests.",
          "$ref": "#/definitions/RequestHeader"
        },
        "enrollmentRequestId": {
          "description": "**REQUIRED**: A reference to an earlier enrollment request. Specifically, the identifier set in the `requestId` of the `requestHeader` sent in the `enrollRequest` that registered a card for {{product_name_short}}. This is a string that has a maximum length of 100 characters.",
          "type": "string"
        },
        "transactionUpdateAvailable": {
          "description": "New transactions or transaction updates are available.",
          "$ref": "#/definitions/Empty"
        },
        "transactionDataDisabled": {
          "description": "Transaction data sharing has been disabled by the user.",
          "$ref": "#/definitions/Empty"
        },
        "transactionDataEnabled": {
          "description": "Transaction data sharing has been enabled by the user.",
          "$ref": "#/definitions/Empty"
        },
        "timestamp": {
          "description": "**REQUIRED**: The timestamp of the event. This is the timestamp of when this event has occurred, not when it was sent.",
          "$ref": "#/definitions/Timestamp"
        }
      }
    },
    "RequestHeader": {
      "description": "Header object that is defined on all requests sent to the server.",
      "type": "object",
      "properties": {
        "requestId": {
          "description": "**REQUIRED**: Unique identifier of this request. This is a string that has a max length of 100 characters, and contains only the characters \"a-z\", \"A-Z\", \"0-9\", \":\", \"-\", and \"_\".",
          "type": "string"
        },
        "requestTimestamp": {
          "description": "**REQUIRED**: Timestamp of this request. The receiver must verify that this timestamp is \u00B1 60s of 'now', and reject the request if it is not. This request timestamp is not idempotent upon retries.",
          "$ref": "#/definitions/Timestamp"
        },
        "protocolVersion": {
          "description": "**REQUIRED**: The version of this request.",
          "$ref": "#/definitions/Version"
        },
        "paymentIntegratorAccountId": {
          "description": "**REQUIRED**: Identifies a unique account with contractual constraints.",
          "type": "string"
        }
      }
    },
    "Timestamp": {
      "description": "A timestamp object representing a point on the ISO timeline in milliseconds since the Unix epoch.",
      "type": "object",
      "properties": {
        "epochMillis": {
          "description": "**REQUIRED**: Milliseconds since the Unix epoch",
          "type": "string",
          "format": "int64"
        }
      }
    },
    "Version": {
      "description": "Version object contains the major version of the API. Versions of the same major version are guaranteed to be compatible. The integrator must support all requests for the same major version.",
      "type": "object",
      "properties": {
        "major": {
          "description": "**REQUIRED**: Major version. This is marked for compatibility requests with different versions are not guaranteed to be compatible.",
          "type": "integer",
          "format": "int32"
        }
      }
    },
    "Empty": {
      "description": " This object is used for extensibility because booleans and enumerations often need to be extended with extra data. The implementer uses it to determine presence. The enumeration this represents may be extended to contain data in future versions. The JSON representation for `Empty` is empty JSON object `{}`.",
      "type": "object",
      "properties": {
      }
    },
    "TransactionEventNotificationResponse": {
      "description": "Response for the `transactionEventNotification` method.",
      "type": "object",
      "properties": {
        "responseHeader": {
          "description": "**REQUIRED**: Common header for all responses.",
          "$ref": "#/definitions/ResponseHeader"
        },
        "result": {
          "description": "**REQUIRED**: Result of this call.",
          "$ref": "#/definitions/TransactionEventNotificationResponseTransactionEventNotificationResult"
        }
      }
    },
    "ResponseHeader": {
      "description": "Header object that is defined on all responses sent from the server.",
      "type": "object",
      "properties": {
        "responseTimestamp": {
          "description": "**REQUIRED**: Timestamp of this response. The receiver must verify that this timestamp is \u00B1 60s of 'now', and reject the response if it is not.",
          "$ref": "#/definitions/Timestamp"
        }
      }
    },
    "TransactionEventNotificationResponseTransactionEventNotificationResult": {
      "description": "Result codes for the `transactionEventNotification` method.",
      "type": "object",
      "properties": {
        "success": {
          "description": "Transaction Event notification was successfully processed.",
          "$ref": "#/definitions/Empty"
        },
        "unknownEnrollment": {
          "description": "Declined because the given `enrollmentRequestId` is not recognized.",
          "$ref": "#/definitions/Empty"
        }
      }
    },
    "ErrorResponse": {
      "description": "Error Response object for all methods.",
      "type": "object",
      "properties": {
        "responseHeader": {
          "description": "**REQUIRED**: Common header for all responses.",
          "$ref": "#/definitions/ResponseHeader"
        },
        "errorDescription": {
          "description": "**OPTIONAL**: Provide a description of this status for support reps to debug errors. Note that this is never shown to users. It can contain descriptive, non-sensitive text used for debugging. Note that some values for errorResponseCode should be accompanied by additional detail in this field. Warning: Do not include any tokens in this message unless they are defined as public.",
          "type": "string"
        },
        "paymentIntegratorErrorIdentifier": {
          "description": "**OPTIONAL**: This identifier is specific to the integrator and is generated by the integrator. It is used for debugging purposes only in order to identify this call. This is the identifier that the integrator knows this call by.",
          "type": "string"
        },
        "errorResponseResult": {
          "description": "**OPTIONAL**: A code that captures the type of error that occurred.",
          "$ref": "#/definitions/ErrorResponseErrorResponseResult"
        }
      }
    },
    "ErrorResponseErrorResponseResult": {
      "description": "Error Codes",
      "type": "object",
      "properties": {
        "invalidApiVersion": {
          "description": "Used if the request's API version is unsupported. Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponseInvalidApiVersion"
        },
        "invalidPayloadSignature": {
          "description": "Used if the signature of the payload is to an unknown or inactive key. Advised HTTP Code: 401",
          "$ref": "#/definitions/ErrorResponseInvalidPayloadSignature"
        },
        "invalidPayloadEncryption": {
          "description": "Used if the encryption of the payload is to an unknown or inactive key. Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponseInvalidPayloadEncryption"
        },
        "requestTimestampOutOfRange": {
          "description": "Used if the request_timestamp is not \u00B1 60s of now. Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponseRequestTimestampOutOfRange"
        },
        "invalidIdentifier": {
          "description": "Used if an identifier sent in the request was invalid or unknown. This may include PIAID, captureRequestId, Google Payment Token, etc. Advised HTTP Code: 404",
          "$ref": "#/definitions/ErrorResponseInvalidIdentifier"
        },
        "idempotencyViolation": {
          "description": "Used if the request violates the idempotency requirements for the request. Advised HTTP Code: 412",
          "$ref": "#/definitions/ErrorResponseIdempotencyViolation"
        },
        "invalidFieldValue": {
          "description": "Used if the request contains a value for a field that isn't in the set of supported values. Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponseInvalidFieldValue"
        },
        "missingRequiredField": {
          "description": "Used if a field that is required is unset in the request. Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponseMissingRequiredField"
        },
        "preconditionViolation": {
          "description": "Used if a constraint on the operation is violated (e.g. when a request for a refund amount exceeds the amount remaining on the transaction). Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponsePreconditionViolation"
        },
        "userActionInProgress": {
          "description": "Used if the request cannot be processed at this time because it would interrupt an in-process user action which effectively acts as a system lock. This code must *not* be used to indicate failures due to implementation-specific internal concurrency errors. Advised HTTP Code: 423",
          "$ref": "#/definitions/ErrorResponseUserActionInProgress"
        },
        "invalidDecryptedRequest": {
          "description": "Used if the request payload could be decrypted, but the resulting message could not be parsed. Advised HTTP Code: 400",
          "$ref": "#/definitions/ErrorResponseInvalidDecryptedRequest"
        },
        "forbidden": {
          "description": "Access to the requested resource is forbidden. Advised Http Code: 403",
          "$ref": "#/definitions/ErrorResponseForbidden"
        }
      }
    },
    "ErrorResponseInvalidApiVersion": {
      "description": "Used if the request's API version is unsupported.",
      "type": "object",
      "properties": {
        "requestVersion": {
          "description": "**REQUIRED**: The invalid version that was specified on the request.",
          "$ref": "#/definitions/Version"
        },
        "expectedVersion": {
          "description": "**REQUIRED**: The expected version.",
          "$ref": "#/definitions/Version"
        }
      }
    },
    "ErrorResponseInvalidPayloadSignature": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "ErrorResponseInvalidPayloadEncryption": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "ErrorResponseRequestTimestampOutOfRange": {
      "description": "Used if the request_timestamp is not \u00B1 60s of now.",
      "type": "object",
      "properties": {
        "requestTimestamp": {
          "description": "**REQUIRED**: The timestamp provided in the request",
          "$ref": "#/definitions/Timestamp"
        },
        "serverTimestampAtReceipt": {
          "description": "**REQUIRED**: The server time at receipt, used for comparison",
          "$ref": "#/definitions/Timestamp"
        }
      }
    },
    "ErrorResponseInvalidIdentifier": {
      "description": "Used if an identifier sent in the request was invalid or unknown. This may include PIAID, captureRequestId, Google Payment Token, etc.",
      "type": "object",
      "properties": {
        "invalidIdentifierType": {
          "description": "**REQUIRED**: The type of identifier that was invalid, e.g. PIAID, captureRequestId, etc.",
          "type": "string"
        }
      }
    },
    "ErrorResponseIdempotencyViolation": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "ErrorResponseInvalidFieldValue": {
      "description": "Used if the request contains a value for a field that isn't in the set of supported values.",
      "type": "object",
      "properties": {
        "invalidFieldName": {
          "description": "**REQUIRED**: The name of the field that was found to be invalid.",
          "type": "string"
        }
      }
    },
    "ErrorResponseMissingRequiredField": {
      "description": "Used if a field that is required is unset in the request.",
      "type": "object",
      "properties": {
        "missingFieldNames": {
          "description": "**REQUIRED**: The names of the missing fields.",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "ErrorResponsePreconditionViolation": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "ErrorResponseUserActionInProgress": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "ErrorResponseInvalidDecryptedRequest": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "ErrorResponseForbidden": {
      "description": "This message is intentionally empty right now. New fields could be added in the future.",
      "type": "object",
      "properties": {
      }
    },
    "EchoRequest": {
      "description": "Request object for the echo method.",
      "type": "object",
      "properties": {
        "requestHeader": {
          "description": "**REQUIRED**: Common header for all requests.",
          "$ref": "#/definitions/RequestHeader"
        },
        "clientMessage": {
          "description": "**REQUIRED**: Message to echo in the response.",
          "type": "string"
        }
      }
    },
    "EchoResponse": {
      "description": "Response object for the echo method.",
      "type": "object",
      "properties": {
        "responseHeader": {
          "description": "**REQUIRED**: Common header for all responses.",
          "$ref": "#/definitions/ResponseHeader"
        },
        "clientMessage": {
          "description": "**REQUIRED**: Message received in the request.",
          "type": "string"
        },
        "serverMessage": {
          "description": "**OPTIONAL**: Server message, independent of the `clientMessage` being echoed.",
          "type": "string"
        }
      }
    }
  }
}
