diff --git a/internal/driver/stripe/client.go b/internal/driver/stripe/client.go index ea6e6b1..69643a0 100644 --- a/internal/driver/stripe/client.go +++ b/internal/driver/stripe/client.go @@ -125,18 +125,37 @@ type CreatePaymentLinkParams struct { // CreatePaymentLink creates a payment link for the provided booking metadata and amount. func (c *Client) CreatePaymentLink(ctx context.Context, params CreatePaymentLinkParams) (string, error) { + linkParams, err := buildPaymentLinkCreateParams(params) + if err != nil { + return "", err + } + + linkParams.Context = ctx + + pl, err := c.api.V1PaymentLinks.Create(ctx, linkParams) + if err != nil { + return "", fmt.Errorf("failed to create payment link: %w", err) + } + + return pl.URL, nil +} + +func buildPaymentLinkCreateParams(params CreatePaymentLinkParams) (*stripe.PaymentLinkCreateParams, error) { if params.Amount <= 0 { - return "", errors.New("amount must be greater than zero") + return nil, errors.New("amount must be greater than zero") } currency := strings.ToLower(strings.TrimSpace(params.Currency)) if currency == "" { - return "", errors.New("currency is required") + return nil, errors.New("currency is required") } if params.BookingID == 0 { - return "", errors.New("booking id is required") + return nil, errors.New("booking id is required") } amountCents := int64(math.Round(params.Amount * 100)) + metadata := map[string]string{ + "booking_id": strconv.FormatUint(uint64(params.BookingID), 10), + } linkParams := &stripe.PaymentLinkCreateParams{ LineItems: []*stripe.PaymentLinkCreateLineItemParams{ @@ -151,8 +170,9 @@ func (c *Client) CreatePaymentLink(ctx context.Context, params CreatePaymentLink Quantity: stripe.Int64(1), }, }, - Metadata: map[string]string{ - "booking_id": strconv.FormatUint(uint64(params.BookingID), 10), + Metadata: metadata, + PaymentIntentData: &stripe.PaymentLinkCreatePaymentIntentDataParams{ + Metadata: metadata, }, } @@ -164,14 +184,7 @@ func (c *Client) CreatePaymentLink(ctx context.Context, params CreatePaymentLink linkParams.PaymentMethodTypes = stripe.StringSlice(params.PaymentMethodTypes) } - linkParams.Context = ctx - - pl, err := c.api.V1PaymentLinks.Create(ctx, linkParams) - if err != nil { - return "", fmt.Errorf("failed to create payment link: %w", err) - } - - return pl.URL, nil + return linkParams, nil } func deriveMethod(pi *stripe.PaymentIntent) string { diff --git a/internal/driver/stripe/client_test.go b/internal/driver/stripe/client_test.go new file mode 100644 index 0000000..5ee8394 --- /dev/null +++ b/internal/driver/stripe/client_test.go @@ -0,0 +1,28 @@ +package stripe + +import "testing" + +func TestBuildPaymentLinkCreateParamsSetsBookingMetadataOnPaymentIntent(t *testing.T) { + params, err := buildPaymentLinkCreateParams(CreatePaymentLinkParams{ + Amount: 120.50, + Currency: "EUR", + BookingID: 42, + Description: "Villa booking", + PaymentMethodTypes: []string{"card"}, + }) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if params.Metadata["booking_id"] != "42" { + t.Fatalf("payment link metadata missing booking id: %+v", params.Metadata) + } + + if params.PaymentIntentData == nil { + t.Fatal("payment intent data should not be nil") + } + + if params.PaymentIntentData.Metadata["booking_id"] != "42" { + t.Fatalf("payment intent metadata missing booking id: %+v", params.PaymentIntentData.Metadata) + } +}