Malformed Order Error
https://bessapay.net/errors/malformed-orderOverview
A Malformed Order error occurs when an order request contains invalid, incomplete, or inconsistent data. This error is more specific than a general validation error as it relates specifically to order processing and business logic issues in order data.
Details
- Error Code: MALFORMED_ORDER
- HTTP Status: 400
- Error Type: Client Error
Common scenarios
- • Inconsistent line items or quantities
- • Invalid product combinations
- • Incomplete shipping or billing information
- • Order total calculation mismatches
- • Invalid discount codes or promotions
Example
1{
2 "type": "https://bessapay.net/errors/malformed-order",
3 "title": "Malformed Order",
4 "status": 400,
5 "detail": "Order contains products that cannot be shipped to the provided address",
6 "instance": "/api/v1/orders",
7 "errorCode": "MALFORMED_ORDER",
8 "timestamp": "2023-06-15T20:30:45Z",
9 "issues": [
10 {
11 "code": "SHIPPING_RESTRICTION",
12 "message": "Product 'PRD-123' cannot be shipped to country 'AU'",
13 "affectedItems": ["PRD-123"]
14 },
15 {
16 "code": "INVALID_COMBINATION",
17 "message": "Products 'PRD-456' and 'PRD-789' cannot be ordered together",
18 "affectedItems": ["PRD-456", "PRD-789"]
19 }
20 ]
21}How to Handle
Check order data integrity
Ensure that all required order fields are present and correctly formatted. Verify that product IDs, quantities, and pricing information are accurate.
Validate product combinations
Some products cannot be ordered together due to shipping restrictions, compatibility issues, or business rules. Implement client-side validation to prevent incompatible combinations.
Verify regional availability
Check if products can be shipped to the customer's address before allowing them to be added to the cart. Consider implementing region-specific product filtering.
Handle issues individually
The error response includes an issues array with specific problems. Process each issue individually and present clear messages to the user about what needs to be fixed.
1// Example of processing individual order issues
2function processOrderIssues(errorData) {
3 // Check if we have specific issues to process
4 if (errorData.issues && Array.isArray(errorData.issues)) {
5 const issuesByType = {
6 SHIPPING_RESTRICTION: [],
7 INVENTORY_ISSUE: [],
8 PRICING_ISSUE: [],
9 INVALID_COMBINATION: [],
10 OTHER: []
11 };
12
13 // Group issues by type
14 errorData.issues.forEach(issue => {
15 if (issuesByType[issue.code]) {
16 issuesByType[issue.code].push(issue);
17 } else {
18 issuesByType.OTHER.push(issue);
19 }
20 });
21
22 // Handle shipping restrictions
23 if (issuesByType.SHIPPING_RESTRICTION.length > 0) {
24 handleShippingRestrictions(issuesByType.SHIPPING_RESTRICTION);
25 }
26
27 // Handle invalid product combinations
28 if (issuesByType.INVALID_COMBINATION.length > 0) {
29 handleInvalidCombinations(issuesByType.INVALID_COMBINATION);
30 }
31
32 // Handle inventory issues
33 if (issuesByType.INVENTORY_ISSUE.length > 0) {
34 handleInventoryIssues(issuesByType.INVENTORY_ISSUE);
35 }
36
37 // Return true if we handled any specific issues
38 return Object.values(issuesByType).some(issues => issues.length > 0);
39 }
40
41 // No specific issues to handle
42 return false;
43}Re-validate on changes
After a user makes changes to fix order issues, re-validate the entire order to ensure no new issues have been introduced.
Code Example: Order Validation and Submission
1// Complete example of order validation and submission
2class OrderService {
3 constructor(apiKey, baseUrl = 'https://api.semuni.com/v1') {
4 this.apiKey = apiKey;
5 this.baseUrl = baseUrl;
6 }
7
8 // Validate an order before submission
9 async validateOrder(orderData) {
10 try {
11 const response = await fetch(`${this.baseUrl}/orders/validate`, {
12 method: 'POST',
13 headers: {
14 'Authorization': `Bearer ${this.apiKey}`,
15 'Content-Type': 'application/json'
16 },
17 body: JSON.stringify(orderData)
18 });
19
20 if (!response.ok) {
21 const errorData = await response.json();
22
23 if (errorData.type === 'https://bessapay.net/errors/malformed-order') {
24 return {
25 valid: false,
26 errors: errorData.issues || [],
27 message: errorData.detail
28 };
29 }
30
31 throw new Error(errorData.detail || 'Order validation failed');
32 }
33
34 return {
35 valid: true
36 };
37 } catch (error) {
38 console.error('Order validation error:', error);
39 throw error;
40 }
41 }
42
43 // Submit an order with pre-validation
44 async submitOrder(orderData) {
45 try {
46 // First validate the order
47 const validation = await this.validateOrder(orderData);
48
49 if (!validation.valid) {
50 return {
51 success: false,
52 stage: 'validation',
53 errors: validation.errors,
54 message: validation.message
55 };
56 }
57
58 // If validation passed, submit the order
59 const response = await fetch(`${this.baseUrl}/orders`, {
60 method: 'POST',
61 headers: {
62 'Authorization': `Bearer ${this.apiKey}`,
63 'Content-Type': 'application/json'
64 },
65 body: JSON.stringify(orderData)
66 });
67
68 if (!response.ok) {
69 const errorData = await response.json();
70
71 // Check if it's a malformed order that passed validation but failed on submission
72 if (errorData.type === 'https://bessapay.net/errors/malformed-order') {
73 return {
74 success: false,
75 stage: 'submission',
76 errors: errorData.issues || [],
77 message: errorData.detail
78 };
79 }
80
81 throw new Error(errorData.detail || 'Order submission failed');
82 }
83
84 const orderResult = await response.json();
85
86 return {
87 success: true,
88 order: orderResult
89 };
90 } catch (error) {
91 console.error('Order submission error:', error);
92 return {
93 success: false,
94 stage: 'system',
95 message: 'An unexpected error occurred. Please try again.'
96 };
97 }
98 }
99
100 // Helper method to fix common order issues
101 fixOrderIssues(orderData, issues) {
102 const fixedOrder = { ...orderData };
103
104 issues.forEach(issue => {
105 switch (issue.code) {
106 case 'SHIPPING_RESTRICTION':
107 // Remove products that can't be shipped
108 if (issue.affectedItems && fixedOrder.items) {
109 fixedOrder.items = fixedOrder.items.filter(item =>
110 !issue.affectedItems.includes(item.productId)
111 );
112 }
113 break;
114
115 case 'INVALID_COMBINATION':
116 // If we have invalid combinations, keep only the first item in each combination
117 if (issue.affectedItems && fixedOrder.items) {
118 const firstItemToKeep = issue.affectedItems[0];
119 fixedOrder.items = fixedOrder.items.filter(item =>
120 item.productId === firstItemToKeep || !issue.affectedItems.includes(item.productId)
121 );
122 }
123 break;
124
125 // Add more issue handlers as needed
126 }
127 });
128
129 return fixedOrder;
130 }
131}
132
133// Usage example
134const orderService = new OrderService('your-api-key');
135
136// Submit an order
137async function placeOrder(orderData) {
138 try {
139 const result = await orderService.submitOrder(orderData);
140
141 if (!result.success) {
142 // Show errors to the user
143 displayOrderErrors(result.errors, result.message);
144
145 // If we can automatically fix some issues, offer that option
146 if (result.errors && result.errors.length > 0) {
147 const fixedOrder = orderService.fixOrderIssues(orderData, result.errors);
148
149 if (fixedOrder.items.length !== orderData.items.length) {
150 offerFixedOrder(fixedOrder);
151 }
152 }
153
154 return null;
155 }
156
157 // Success! Show confirmation
158 showOrderConfirmation(result.order);
159 return result.order;
160 } catch (error) {
161 console.error('Error placing order:', error);
162 showGenericError('We encountered a problem while processing your order. Please try again.');
163 return null;
164 }
165}