Files
Crussell/backend/internal/square/square.go
T
popertots 01ac211408 Square client and dev mock: replay-by-key reconcile, refund classification, mock parity
ReplayPaymentByKey (POST /v2/payments re-issue with the same idempotency key
and a synthetic probe source token that can never process a real charge):
Square returns the ORIGINAL payment for a retained key and definitively
rejects an unknown/expired one, so the stale-pending sweep can rescue
lost-response charges without ever issuing a second payment. ErrReplayKeyNotRetained
marks a probe rejection as proof the charge never happened.

Refund classification: zero-amount refunds are now rejected (Square requires
amount_money) instead of lenient full-refund; REFUND_ALREADY_PENDING is
classified as already-processed to match the real contract.

Dev mock parity: SquarePayID == payment ID (was fabricated 'sqp_' prefix),
ForceCheckoutState for IN_PROGRESS/CANCEL_REQUESTED terminal states,
replay-by-key support, aligned refund error codes.
2026-08-22 00:34:49 +01:00

73 lines
2.1 KiB
Go

//go:build !dev
package square
import (
"context"
"time"
)
var Client SquareClient
type ProdClient struct{}
func NewClient() SquareClient {
return NewProdClient()
}
func NewProdClient() SquareClient {
return &ProdClient{}
}
func (p *ProdClient) CreatePayment(ctx context.Context, req CreatePaymentReq) (*PaymentResult, error) {
return createPaymentHTTP(ctx, req)
}
func (p *ProdClient) CreateCheckout(ctx context.Context, req CreateCheckoutReq) (*CheckoutResult, error) {
return createCheckoutHTTP(ctx, req)
}
func (p *ProdClient) GetCheckout(ctx context.Context, checkoutID string) (*PaymentResult, error) {
return getCheckoutHTTP(ctx, checkoutID)
}
func (p *ProdClient) GetPayment(ctx context.Context, paymentID string) (*PaymentResult, error) {
return getPaymentHTTP(ctx, paymentID)
}
func (p *ProdClient) ReplayPaymentByKey(ctx context.Context, idempotencyKey string, amount int64) (*PaymentResult, error) {
return replayPaymentByKeyHTTP(ctx, idempotencyKey, amount)
}
func (p *ProdClient) CreateCustomer(ctx context.Context, name, email string) (*CustomerResult, error) {
return createCustomerHTTP(ctx, name, email)
}
func (p *ProdClient) DeleteCustomer(ctx context.Context, customerID string) error {
return deleteCustomerHTTP(ctx, customerID)
}
func (p *ProdClient) CancelCheckout(ctx context.Context, checkoutID string) error {
return cancelCheckoutHTTP(ctx, checkoutID)
}
func (p *ProdClient) RefundPayment(ctx context.Context, req RefundPaymentReq) (*RefundResult, error) {
return refundPaymentHTTP(ctx, req)
}
func (p *ProdClient) CreateCardOnFile(ctx context.Context, userID, cardToken, customerID string) (*CardOnFile, error) {
return createCardOnFileHTTP(ctx, userID, cardToken, customerID)
}
func (p *ProdClient) GetCardsOnFile(ctx context.Context, userID string) ([]CardOnFile, error) {
return getCardsOnFileHTTP(ctx, userID)
}
func (p *ProdClient) DeleteCardOnFile(ctx context.Context, cardID string) error {
return deleteCardOnFileHTTP(ctx, cardID)
}
func (p *ProdClient) ListPaymentRefunds(ctx context.Context, paymentID string, beginTime time.Time) ([]RefundResult, error) {
return listRefundsHTTP(ctx, paymentID, beginTime)
}