{"openapi":"3.0.3","info":{"title":"Outdoors Payments Hub (OPH)","version":"0.1.0"},"externalDocs":{"description":"swagger.json","url":"/swagger.json"},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"},"TenantCode":{"type":"apiKey","in":"header","name":"X-Tenant-Code"},"Environment":{"type":"apiKey","in":"header","name":"X-Environment"}},"schemas":{"CreateAddIFrameRequest":{"type":"object","required":["email","isGuest"],"properties":{"firstName":{"type":"string","description":"First name (optional)"},"lastName":{"type":"string","description":"Last name (optional)"},"email":{"type":"string","format":"email","description":"User email"},"isGuest":{"type":"boolean","description":"Is guest user"}}},"CreateEditIFrameRequest":{"type":"object","required":["walletId","paymentAccountId"],"properties":{"walletId":{"type":"string","format":"uuid"},"paymentAccountId":{"type":"string","format":"uuid"}}},"AuthorizeRequest":{"type":"object","description":"Saved payment request. Requires PaymentAccountId, WalletId/ClientUserId, and PaymentLineItems. Note: PortalId, MerchantId, MerchantKey, ServiceCode come from tenant config.","properties":{"WalletId":{"type":"string","format":"uuid","description":"Wallet identifier (required for saved payments if ClientUserId not provided)","example":"123e4567-e89b-12d3-a456-426614174000"},"ClientUserId":{"type":"string","description":"Client user identifier (required for saved payments if WalletId not provided)","example":"user-12345"},"PaymentAccountId":{"type":"string","format":"uuid","description":"Payment account identifier (required for saved payments)","example":"123e4567-e89b-12d3-a456-426614174001"},"Action":{"type":"string","enum":["auth","capture"],"description":"Payment action - auth to authorize funds (default), capture to capture funds","example":"auth"},"Cvv":{"type":"string","description":"Card CVV code (optional for saved payments, should not be reused)","example":"123"},"CachedCvvToken":{"type":"string","description":"Cached CVV token (optional for saved payments, expires after 30 seconds)","example":"cached-cvv-token-abc123"},"PaymentLineItems":{"type":"array","minItems":1,"description":"Array of payment line items (required for saved payments, at least one required)","items":{"type":"object","required":["Description","UnitPrice","Quantity","Sku"],"properties":{"Description":{"type":"string","description":"Line item description","example":"Court fees payment"},"UnitPrice":{"type":"number","format":"double","minimum":0.01,"description":"Unit price for the line item","example":12.34},"Quantity":{"type":"integer","minimum":1,"description":"Quantity of items","example":1},"Sku":{"type":"string","description":"Stock keeping unit identifier","example":"FEE-001"},"Type":{"type":"string","description":"Optional line item type","example":"Legacy"},"InstanceId":{"type":"string","description":"Optional instance identifier","example":"instance-123"}}}},"Customer":{"type":"object","description":"Optional customer information (for saved payments)","properties":{"FirstName":{"type":"string","description":"Customer first name","example":"John"},"LastName":{"type":"string","description":"Customer last name","example":"Doe"},"EmailAddress":{"type":"string","format":"email","description":"Customer email address","example":"john.doe@example.com"},"PhoneNumber":{"type":"string","description":"Customer phone number","example":"+1-555-123-4567"},"IpAddress":{"type":"string","format":"ipv4","description":"Customer IP address","example":"192.168.1.1"},"Address":{"type":"object","description":"Customer address","properties":{"Address1":{"type":"string","description":"Primary address line","example":"123 Main Street"},"Address2":{"type":"string","description":"Secondary address line (optional)","example":"Suite 100"},"City":{"type":"string","description":"City","example":"Springfield"},"State":{"type":"string","description":"State or province","example":"IL"},"PostalCode":{"type":"string","description":"Postal or ZIP code","example":"62701"},"Country":{"type":"string","description":"Country code or name","example":"USA"}},"required":["Address1","City","State","PostalCode","Country"]}}}}},"CaptureRequest":{"type":"object","required":["orderId"],"properties":{"orderId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}},"RefundRequest":{"type":"object","required":["orderId"],"properties":{"orderId":{"type":"string"},"reason":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}},"AddPaymentMethodRequest":{"type":"object","required":["customerId"],"properties":{"customerId":{"type":"string"},"type":{"type":"string","enum":["card","ach","token"]},"details":{"type":"object","additionalProperties":true}}},"EditPaymentMethodRequest":{"type":"object","required":["updates"],"properties":{"updates":{"type":"object","additionalProperties":true}}},"GetIFrameResponse":{"type":"object","properties":{"iframeUrl":{"type":"string","description":"URL to the payment iframe"},"walletId":{"type":"string","format":"uuid"},"paymentMethodId":{"type":"string","format":"uuid"},"canSavePaymentMethod":{"type":"boolean","description":"Whether the payment method can be saved (false for guest users or users without an emailAddress)"},"paymentMethodSaveResult":{"type":"string","enum":["PaymentSaved","NoEmailNotSaved","GuestNotSaved"],"description":"Result indicating the payment method saving status"}}},"SavedPaymentRequest":{"type":"object","required":["PaymentAccountId","Action","PaymentLineItems"],"properties":{"WalletId":{"type":"string","format":"uuid","description":"Wallet identifier (required if ClientUserId is not provided)","example":"123e4567-e89b-12d3-a456-426614174000"},"ClientUserId":{"type":"string","description":"Client user identifier (required if WalletId is not provided)","example":"user-12345"},"PaymentAccountId":{"type":"string","format":"uuid","description":"Payment account identifier","example":"123e4567-e89b-12d3-a456-426614174001"},"Action":{"type":"string","enum":["auth","capture"],"description":"Payment action - auth to authorize funds, capture to capture funds"},"Cvv":{"type":"string","description":"Card CVV code (optional, should not be reused)","example":"123"},"CachedCvvToken":{"type":"string","description":"Cached CVV token (optional, expires after 30 seconds)","example":"cached-cvv-token-abc123"},"PaymentLineItems":{"type":"array","minItems":1,"description":"Array of payment line items (at least one required)","items":{"type":"object","required":["Type","Description","Amount"],"properties":{"Type":{"type":"string","description":"Line item type","example":"Legacy"},"Description":{"type":"string","description":"Line item description","example":"Court fees payment"},"Amount":{"type":"number","format":"double","minimum":0.01,"description":"Line item amount","example":12.34},"InstanceId":{"type":"string","description":"Optional instance identifier","example":"instance-123"}}}},"Customer":{"type":"object","description":"Optional customer information","properties":{"FirstName":{"type":"string","description":"Customer first name","example":"John"},"LastName":{"type":"string","description":"Customer last name","example":"Doe"},"EmailAddress":{"type":"string","format":"email","description":"Customer email address","example":"john.doe@example.com"},"PhoneNumber":{"type":"string","description":"Customer phone number","example":"+1-555-123-4567"},"IpAddress":{"type":"string","format":"ipv4","description":"Customer IP address","example":"192.168.1.1"},"Address":{"type":"object","description":"Customer address","properties":{"Address1":{"type":"string","description":"Primary address line","example":"123 Main Street"},"Address2":{"type":"string","description":"Secondary address line (optional)","example":"Suite 100"},"City":{"type":"string","description":"City","example":"Springfield"},"State":{"type":"string","description":"State or province","example":"IL"},"PostalCode":{"type":"string","description":"Postal or ZIP code","example":"62701"},"Country":{"type":"string","description":"Country code or name","example":"USA"}},"required":["Address1","City","State","PostalCode","Country"]}}}}},"SavedPaymentResponse":{"type":"object","description":"TPE order structure response","properties":{"OrderId":{"type":"string","description":"Order identifier","example":"ORD-123456789"},"AuthorizationStatus":{"type":"string","description":"Authorization status","example":"Authorized"},"ProcessorResponseCode":{"type":"string","description":"Processor response code","example":"00"},"AuthorizationCode":{"type":"string","description":"Authorization code","example":"AUTH123456"},"CardType":{"type":"string","description":"Card type","example":"Visa"},"ResponseCode":{"type":"string","description":"Response code (00 typically indicates success)","example":"00"},"ResponseMessage":{"type":"string","description":"Response message","example":"Approved"},"PaymentAccountId":{"type":"string","format":"uuid","description":"Payment account identifier used","example":"123e4567-e89b-12d3-a456-426614174001"},"AuthAmount":{"type":"number","format":"double","description":"Authorized amount","example":12.34},"Reason":{"type":"string","description":"Decline reason (present if payment was declined)","example":"Insufficient funds"},"raw":{"type":"object","description":"Raw response from processor (for debugging)","additionalProperties":true}}},"PaymentResult":{"type":"object","description":"Payment result from processor","properties":{"id":{"type":"string","description":"Payment identifier","example":"payment-123"},"status":{"type":"string","enum":["authorized","captured","refunded","failed","pending"],"description":"Payment status","example":"authorized"},"reference":{"type":"string","description":"Payment reference code (e.g., authorization code)","example":"AUTH123456"},"raw":{"type":"object","description":"Raw response from processor (for debugging)","additionalProperties":true}},"required":["id","status"]},"ShoppingCartItem":{"type":"object","required":["productId","customerForId","dateAdded","dateExpires","moduleCode","cartItemId","parentCartItemId","productType","productCode","productName","inventoryId","guestUuid","agentId","data"],"properties":{"productId":{"type":"string","description":"Product identifier"},"customerForId":{"type":"integer","description":"Customer ID"},"dateAdded":{"type":"string","format":"date-time","description":"Date when item was added"},"dateExpires":{"type":"string","format":"date-time","description":"Date when item expires"},"moduleCode":{"type":"string","description":"Module code"},"cartItemId":{"type":"string","description":"Cart item ID"},"parentCartItemId":{"type":"string","description":"Parent cart item ID"},"productType":{"type":"string","description":"Product type"},"productCode":{"type":"string","description":"Product code"},"productName":{"type":"string","description":"Product name"},"inventoryId":{"type":"integer","description":"Inventory ID"},"guestUuid":{"type":"string","description":"Guest UUID"},"agentId":{"type":"integer","description":"Agent ID"},"data":{"type":"string","description":"Additional data"}}},"PaymentAttempt":{"type":"object","required":["clientCode","customerId","dateCreated","paymentAttemptDetails"],"properties":{"clientCode":{"type":"string","description":"Client code identifier"},"customerId":{"type":"integer","description":"Customer ID"},"dateCreated":{"type":"string","format":"date-time","description":"Date when payment attempt was created"},"paymentAttemptDetails":{"type":"object","required":["transaction","connection","payment","response","merchant","reversal"],"properties":{"transaction":{"type":"object","properties":{"amount":{"type":"number"},"trxId":{"type":"integer","description":"Transaction ID"}}},"connection":{"type":"object","properties":{"clientIpAddress":{"type":"string"},"userAgent":{"type":"string"}}},"payment":{"type":"object","properties":{"walletId":{"type":"string"},"cardType":{"type":"string"},"encryptedCreditCardExpiry":{"type":"string"},"encryptedCardLast4":{"type":"string"},"nameOnCard":{"type":"string"},"billingAddress":{"type":"object"}}},"response":{"type":"object","properties":{"referenceId":{"type":"string"},"confirmationCode":{"type":"string"},"authorizationStatus":{"type":"string"},"authorizationStatusText":{"type":"string"},"responseToken":{"type":"string"},"cvvResponse":{"type":"string"},"zipResponse":{"type":"string"}}},"merchant":{"type":"object","properties":{"cardProcessor":{"type":"string"},"merchantId":{"type":"string"}}},"reversal":{"type":"object","properties":{"isReverse":{"type":"boolean"},"reverseReferenceId":{"type":"string"},"refundId":{"type":"string"}}},"shoppingCartItems":{"type":"array","nullable":true,"items":{"$ref":"#/components/schemas/ShoppingCartItem"},"description":"Array of shopping cart items"}}}}}}},"security":[{"ApiKeyAuth":[],"TenantCode":[],"Environment":[]}],"paths":{"/api/v1/payment-attempt":{"post":{"summary":"Create a new payment attempt","tags":["Payment Attempt"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentAttempt"}}}},"responses":{"201":{"description":"Payment attempt created successfully"}}},"get":{"summary":"Get all payment attempts for the client","tags":["Payment Attempt"],"parameters":[{"in":"query","name":"dateFrom","schema":{"type":"string","format":"date-time"},"description":"Filter payment attempts created after this date"},{"in":"query","name":"dateTo","schema":{"type":"string","format":"date-time"},"description":"Filter payment attempts created before this date"},{"in":"query","name":"trxId","schema":{"type":"integer"},"description":"Filter by transaction ID"},{"in":"query","name":"confirmationCode","schema":{"type":"string"},"description":"Filter by confirmation code"},{"in":"query","name":"lastName","schema":{"type":"string"},"description":"Filter by cardholder's last name (case-insensitive partial match)"},{"in":"query","name":"zip","schema":{"type":"string"},"description":"Filter by billing address zip code"}],"responses":{"200":{"description":"List of payment attempts","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentAttempt"}}}}}}}},"/api/v1/payment-attempt/{id}":{"get":{"summary":"Get a specific payment attempt by ID","tags":["Payment Attempt"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Payment attempt details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentAttempt"}}}},"404":{"description":"Payment attempt not found"}}}},"/api/v1/payments/authorize":{"post":{"tags":["Payments"],"summary":"Authorize a payment (supports both regular and saved payment methods)","description":"This endpoint supports two payment types:\n1. Regular payments: Requires amount and currency. Optional customerId, paymentMethodId, lineItems.\n2. Saved payment methods: Requires PaymentAccountId, WalletId/ClientUserId, and PaymentLineItems.\n   - A valid WalletId or ClientUserId must be provided\n   - PaymentLineItems are required (at least one line item)\n   - CVV can be optionally sent (should not be reused, must be freshly collected)\n   - CachedCvvToken can be used instead of raw CVV (expires after 30 seconds)\n   - Card-based payments are supported. ACH is not supported for saved payment authorizations.\n   - Action field: \"auth\" to authorize funds (default), \"capture\" to capture funds\n","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeRequest"},"example":{"IsGuest":false,"WalletId":"123e4567-e89b-12d3-a456-426614174000","ClientUserId":"user-12345","PaymentAccountId":"123e4567-e89b-12d3-a456-426614174001","Action":"auth","Cvv":"123","CachedCvvToken":"cached-cvv-token-abc123","PaymentLineItems":[{"Description":"Court filing fee","UnitPrice":75,"Quantity":1,"Sku":"FEE-001","Type":"Legacy","InstanceId":"instance-123"},{"Description":"Processing fee","UnitPrice":5,"Quantity":2,"Sku":"FEE-002","Type":"Legacy"}],"Customer":{"FirstName":"John","LastName":"Doe","EmailAddress":"john.doe@example.com","PhoneNumber":"+1-555-123-4567","IpAddress":"192.168.1.1","Address":{"Address1":"123 Main Street","Address2":"Suite 100","City":"Springfield","State":"IL","PostalCode":"62701","Country":"USA"}}}}}},"responses":{"200":{"description":"Payment processed successfully (saved payment method)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedPaymentResponse"}}}},"202":{"description":"Payment authorization accepted (regular payment)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentResult"}}}},"400":{"description":"Validation error, line items not allowed, or payment declined"},"401":{"description":"Unauthorized"},"404":{"description":"Wallet or payment account not found (saved payments only)"}}}},"/api/v1/payments/capture":{"post":{"tags":["Payments"],"summary":"Capture a payment","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureRequest"}}}},"responses":{"202":{"description":"Accepted (stub)"}}}},"/api/v1/payments/cancel":{"post":{"tags":["Payments"],"summary":"Cancel a payment","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefundRequest"}}}},"responses":{"202":{"description":"Accepted (stub)"}}}},"/api/v1/payments/{id}/status":{"get":{"tags":["Payments"],"summary":"Get payment status","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Status returned"}}}},"/api/v1/payment-methods":{"post":{"tags":["Payment Methods"],"summary":"Add a payment method","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddPaymentMethodRequest"}}}},"responses":{"202":{"description":"Accepted (stub)"}}}},"/api/v1/payment-methods/:paymentMethodId":{"get":{"tags":["Payments"],"summary":"Get payment method details","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"parameters":[{"in":"path","name":"paymentMethodId","required":true,"schema":{"type":"string"}},{"in":"query","name":"isGuest","required":true,"schema":{"type":"boolean"},"description":"Whether the request is for a guest user"}],"responses":{"200":{"description":"Payment method returned"}}}},"/api/v1/payment-methods/{id}":{"put":{"tags":["Payment Methods"],"summary":"Edit a payment method","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditPaymentMethodRequest"}}}},"responses":{"202":{"description":"Accepted (stub)"}}},"get":{"tags":["Payment Methods"],"summary":"Get a payment method","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payment method returned"}}}},"/api/v1/payment-methods/{walletId}/{paymentMethodId}":{"delete":{"tags":["Payment Methods"],"summary":"Delete payment method","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"parameters":[{"in":"path","name":"walletId","required":true,"schema":{"type":"string"}},{"in":"path","name":"paymentMethodId","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted"}}}},"/api/v1/payments/createAddIFrame":{"post":{"tags":["Payments"],"summary":"Create payment iframe","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAddIFrameRequest"}}}},"responses":{"200":{"description":"IFrame URL/content returned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetIFrameResponse"}}}}}}},"/api/v1/payments/createEditIFrame":{"post":{"tags":["Payments"],"summary":"Create edit payment iframe","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEditIFrameRequest"}}}},"responses":{"200":{"description":"IFrame URL/content returned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetIFrameResponse"}}}}}}},"/api/v1/payment-methods/wallet/{walletId}":{"get":{"tags":["Payment Methods"],"summary":"List saved payment methods for a wallet","description":"Calls the processor to retrieve saved payment accounts (e.g., Tyler /paymentAccount/list).","security":[{"ApiKeyAuth":[]},{"TenantCode":[]},{"Environment":[]}],"parameters":[{"in":"path","name":"walletId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"countryIsoFormat","required":false,"schema":{"type":"string","enum":["name","2letter","3letter"],"default":"name"}}],"responses":{"200":{"description":"Methods returned"},"400":{"description":"Invalid or missing walletId"},"401":{"description":"Unauthorized (auth headers missing/invalid)"},"404":{"description":"Wallet not found"}}}},"/api/v1/user":{"post":{"summary":"Add a new user","tags":["User"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string","example":"John"},"lastName":{"type":"string","example":"Doe"},"emailAddress":{"type":"string","example":"wrenmay9@cat.com"}},"required":["emailAddress"]}}}},"responses":{"200":{"description":"User added successfully"},"400":{"description":"Invalid request body"},"401":{"description":"Unauthorized"},"500":{"description":"Server error"}}}},"/api/v1/user/{walletId}":{"get":{"summary":"Retrieve user wallet information by wallet ID","tags":["User"],"parameters":[{"in":"path","name":"walletId","required":true,"schema":{"type":"string"},"description":"The unique ID of the wallet to fetch","example":"ecc7a177-e912-4dbe-b03f-ad1800b08814"}],"responses":{"200":{"description":"Wallet details retrieved successfully"},"400":{"description":"Missing or invalid wallet ID"},"401":{"description":"Unauthorized"},"500":{"description":"Server error"}}}}},"tags":[{"name":"User","description":"User management and wallet retrieval"}]}