@@ -63,75 +63,124 @@ describe('Checkout Contracts', () => {
6363 successUrl : 'https://example.com/success' ,
6464 allowDiscountCodes : true ,
6565 metadata : { orderId : 'order_123' } ,
66- customerName : 'John Doe' ,
67- customerEmail : 'john@example.com' ,
68- customerIpAddress : '192.168.1.1' ,
69- customerExternalId : 'customer_ext_123' ,
70- requireCustomerFields : {
71- customerName : true ,
72- customerEmail : false ,
66+ customer : {
67+ name : 'John Doe' ,
68+ email : 'john@example.com' ,
69+ plan : 'pro' ,
7370 } ,
71+ requireCustomerData : [ 'email' , 'name' ] ,
7472 } ;
7573
7674 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
7775 expect ( result . success ) . toBe ( true ) ;
7876 } ) ;
7977
80- test ( 'should reject invalid email format ' , ( ) => {
78+ test ( 'should validate requireCustomerData with just email ' , ( ) => {
8179 const input = {
82- customerEmail : 'invalid-email' ,
80+ nodeId : 'node_123' ,
81+ requireCustomerData : [ 'email' ] ,
8382 } ;
8483
8584 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
86- expect ( result . success ) . toBe ( false ) ;
85+ expect ( result . success ) . toBe ( true ) ;
8786 } ) ;
8887
89- test ( 'should reject invalid IP address format ' , ( ) => {
88+ test ( 'should validate requireCustomerData with custom field ' , ( ) => {
9089 const input = {
91- customerIpAddress : 'not-an-ip' ,
90+ nodeId : 'node_123' ,
91+ requireCustomerData : [ 'email' , 'company' ] ,
92+ customer : {
93+ email : 'john@example.com' ,
94+ company : 'Acme Inc' ,
95+ } ,
9296 } ;
9397
9498 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
95- expect ( result . success ) . toBe ( false ) ;
99+ expect ( result . success ) . toBe ( true ) ;
96100 } ) ;
97101
98- test ( 'should reject empty string for customerName ' , ( ) => {
102+ test ( 'should accept any non- empty string in requireCustomerData (custom fields) ' , ( ) => {
99103 const input = {
100- customerName : '' ,
104+ nodeId : 'node_123' ,
105+ requireCustomerData : [ 'email' , 'company' , 'billingAddress' ] ,
106+ } ;
107+
108+ const result = CreateCheckoutInputSchema . safeParse ( input ) ;
109+ expect ( result . success ) . toBe ( true ) ;
110+ } ) ;
111+
112+ test ( 'should reject empty string in requireCustomerData' , ( ) => {
113+ const input = {
114+ nodeId : 'node_123' ,
115+ requireCustomerData : [ 'email' , '' ] ,
101116 } ;
102117
103118 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
104119 expect ( result . success ) . toBe ( false ) ;
105120 } ) ;
106121
107- test ( 'should reject empty string for customerExternalId ' , ( ) => {
122+ test ( 'should reject invalid email format in customer ' , ( ) => {
108123 const input = {
109- customerExternalId : '' ,
124+ nodeId : 'node_123' ,
125+ customer : {
126+ email : 'invalid-email' ,
127+ } ,
110128 } ;
111129
112130 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
113131 expect ( result . success ) . toBe ( false ) ;
114132 } ) ;
115133
116- test ( 'should validate IPv4 address ' , ( ) => {
134+ test ( 'should transform empty string for customer name to undefined ' , ( ) => {
117135 const input = {
118136 nodeId : 'node_123' ,
119- customerIpAddress : '192.168.1.1' ,
137+ customer : {
138+ name : '' ,
139+ } ,
120140 } ;
121141
122142 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
123143 expect ( result . success ) . toBe ( true ) ;
144+ if ( result . success ) {
145+ expect ( result . data . customer ?. name ) . toBeUndefined ( ) ;
146+ }
124147 } ) ;
125148
126- test ( 'should validate IPv6 address ' , ( ) => {
149+ test ( 'should validate create checkout with customer custom fields ' , ( ) => {
127150 const input = {
128151 nodeId : 'node_123' ,
129- customerIpAddress : '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ,
152+ customer : {
153+ userId : 'user_123' ,
154+ plan : 'pro' ,
155+ accountRef : 'acct_456' ,
156+ } ,
130157 } ;
131158
132159 const result = CreateCheckoutInputSchema . safeParse ( input ) ;
133160 expect ( result . success ) . toBe ( true ) ;
134161 } ) ;
162+
163+ test ( 'should only accept string values in custom fields' , ( ) => {
164+ const validInput = {
165+ nodeId : 'node_123' ,
166+ customer : {
167+ userId : 'user_123' ,
168+ company : 'Acme Inc' ,
169+ } ,
170+ } ;
171+
172+ const invalidInput = {
173+ nodeId : 'node_123' ,
174+ customer : {
175+ userId : 'user_123' ,
176+ count : 42 , // numbers not allowed
177+ } ,
178+ } ;
179+
180+ expect ( CreateCheckoutInputSchema . safeParse ( validInput ) . success ) . toBe ( true ) ;
181+ expect ( CreateCheckoutInputSchema . safeParse ( invalidInput ) . success ) . toBe ( false ) ;
182+ } ) ;
183+
135184 } ) ;
136185
137186 describe ( 'ConfirmCheckoutInputSchema' , ( ) => {
@@ -147,10 +196,10 @@ describe('Checkout Contracts', () => {
147196 test ( 'should validate confirm checkout input with all fields' , ( ) => {
148197 const input = {
149198 checkoutId : 'checkout_123' ,
150- customerName : 'John Doe' ,
151- customerEmail : 'john@example.com ' ,
152- customerIpAddress : '192.168.1.1 ' ,
153- customerExternalId : 'customer_ext_123' ,
199+ customer : {
200+ name : 'John Doe ' ,
201+ email : 'john@example.com ' ,
202+ } ,
154203 products : [
155204 {
156205 productId : 'product_1' ,
@@ -168,7 +217,9 @@ describe('Checkout Contracts', () => {
168217
169218 test ( 'should reject confirm checkout without checkoutId' , ( ) => {
170219 const input = {
171- customerName : 'John Doe' ,
220+ customer : {
221+ name : 'John Doe' ,
222+ } ,
172223 } ;
173224
174225 const result = ConfirmCheckoutInputSchema . safeParse ( input ) ;
@@ -187,6 +238,26 @@ describe('Checkout Contracts', () => {
187238 const result = ConfirmCheckoutInputSchema . safeParse ( input ) ;
188239 expect ( result . success ) . toBe ( true ) ;
189240 } ) ;
241+
242+ test ( 'should accept custom fields from confirm input (form fields)' , ( ) => {
243+ // Custom fields are accepted at confirm time - they come from the form
244+ const input = {
245+ checkoutId : 'checkout_123' ,
246+ customer : {
247+ name : 'John Doe' ,
248+ billingAddress : '123 Main St' ,
249+ planId : 'pro' ,
250+ } ,
251+ } ;
252+
253+ const result = ConfirmCheckoutInputSchema . safeParse ( input ) ;
254+ expect ( result . success ) . toBe ( true ) ;
255+ if ( result . success ) {
256+ expect ( result . data . customer ) . toHaveProperty ( 'name' ) ;
257+ expect ( result . data . customer ) . toHaveProperty ( 'billingAddress' ) ;
258+ expect ( result . data . customer ) . toHaveProperty ( 'planId' ) ;
259+ }
260+ } ) ;
190261 } ) ;
191262
192263 describe ( 'ApplyDiscountCodeInputSchema' , ( ) => {
0 commit comments