Order reference
Send an order once.
Retry with confidence.
Submit a JSON order for your assigned source. Your consumer key determines the source, and the external order ID protects against duplicate queue entries.
Order payload
Use the order ID from your own internal system as external_order_id. This lets you and Medidenta reference the same order across platforms. Send buying_group and the payment object on every order, along with billing, shipping, license information, and line items. Save the following payload as order.json for the language examples. Replace example values with the actual order details.
{
"external_order_id": "123456",
"buying_group": "GROUP NAME HERE",
"payment": {
"payment_reference": "PAYMENT-REF-NUM",
"transaction_id": "TRANSACTION_ID",
"payment_method": "SOLA/STRIPE/ETC/INVOICE",
"payment_method_title": "SOLA Payments"
},
"billing": {
"first_name": "John",
"last_name": "Doe",
"company": "Example Company",
"address_1": "5430 East Woodmen Rd",
"address_2": "",
"city": "Colorado Springs",
"state": "CO",
"postcode": "80920",
"country": "US",
"email": "[email protected]",
"phone": "555-555-5555"
},
"shipping": {
"first_name": "John",
"last_name": "Doe",
"company": "Example Company",
"address_1": "5430 East Woodmen Rd",
"address_2": "",
"city": "Colorado Springs",
"state": "CO",
"postcode": "80920",
"country": "US"
},
"license": {
"license_number": "10865",
"license_type": "State Dental",
"license_agency": "TN",
"expiration_date": "2027-04-30 00:00:00-04"
},
"line_items": [
{
"sku": "WI-DELUXE",
"name": "Product Name",
"description": "Product description",
"quantity": 1,
"unit_price": "89.99",
"amount": "89.99"
}
]
}Intake parameters
| Field | Required | Description |
|---|---|---|
external_order_id | Yes | The order ID your internal system uses, such as 123456. This is the cross-platform reference for the order. Send it unchanged and reuse it on retries. |
buying_group | Yes | The buying group associated with the buyer. Send the actual group name. |
payment | Yes | Payment reference, transaction ID, payment method, and payment method title from your platform. |
billing | Yes | Buyer name, company, billing address, email, and phone number. |
shipping | Yes | Recipient name, company, and delivery address. |
license | Yes | Buyer’s professional license number, type, issuing agency, and expiration date. |
line_items | Yes | Array of ordered products, including SKU, name, description, quantity, unit price, and extended line amount. |
Payment details
Include the payment object even when the order is invoiced. These values describe payment in your system; submitting them does not create a charge, capture a payment, or issue a refund.
| Field | Purpose |
|---|---|
payment.payment_reference | Your payment reference number for cross-platform reconciliation. |
payment.transaction_id | The transaction ID from your payment processor, where applicable. Coordinate invoice-only values with Medidenta. |
payment.payment_method | The payment method or provider, such as SOLA, STRIPE, or INVOICE. Send the applicable value, not the combined list shown in the example. |
payment.payment_method_title | Human-readable payment method name, such as SOLA Payments. |
Buyer, delivery, license, and item details
| Field | Purpose |
|---|---|
buying_group | Buying group name associated with the buyer. Required with each order. |
billing | Buyer contact and billing address, including company, email, and phone. |
shipping | Delivery contact, company, and address. |
license | Professional license details: license_number, license_type, license_agency, and expiration_date. |
line_items | Products to fulfill, including SKU, name, description, and quantity. |
line_items[].unit_price | Price per unit, in the agreed order format. |
line_items[].amount | Extended line amount: unit price multiplied by quantity. The example sends one unit at 89.99 for an amount of 89.99. |
Request examples
All examples use the same order.json payload and HTTP Basic Auth. Running them submits a real order; coordinate test IDs and test orders with Medidenta first.
cURL
# Save the order payload shown above as order.json.
curl --silent --show-error --fail-with-body \
--user "$MEDIDENTA_CONSUMER_KEY:$MEDIDENTA_CONSUMER_SECRET" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--request POST \
--data-binary @order.json \
"https://hub.medidenta.com/api/orders.php"JavaScript
// Server-side Node.js 18+. Save the payload as order.json.
const fs = require('node:fs');
async function submitOrder() {
const key = process.env.MEDIDENTA_CONSUMER_KEY;
const secret = process.env.MEDIDENTA_CONSUMER_SECRET;
if (!key || !secret) throw new Error('Configure API credentials');
const order = JSON.parse(fs.readFileSync('order.json', 'utf8'));
const response = await fetch('https://hub.medidenta.com/api/orders.php', {
method: 'POST',
headers: {
Authorization: 'Basic ' + Buffer.from(key + ':' + secret).toString('base64'),
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(order)
});
const data = await response.json();
if (!response.ok) throw new Error(`HTTP ${response.status}: ${data.code}`);
console.log(data.external_order_id, data.duplicate);
}
submitOrder().catch(error => {
console.error(error.message);
process.exitCode = 1;
});Python
# Python 3 standard library. Save the payload as order.json.
import os, json, base64
from urllib.request import Request, urlopen
from urllib.error import HTTPError
key = os.environ['MEDIDENTA_CONSUMER_KEY']
secret = os.environ['MEDIDENTA_CONSUMER_SECRET']
auth = base64.b64encode(f'{key}:{secret}'.encode()).decode()
with open('order.json', encoding='utf-8') as file:
order = json.load(file)
request = Request('https://hub.medidenta.com/api/orders.php',
data=json.dumps(order).encode(), method='POST', headers={
'Authorization': 'Basic ' + auth,
'Accept': 'application/json',
'Content-Type': 'application/json'
})
try:
with urlopen(request, timeout=60) as response:
data = json.load(response)
print(data['external_order_id'], data['duplicate'])
except HTTPError as error:
detail = json.loads(error.read())
raise RuntimeError(f"HTTP {error.code}: {detail.get('code')}") from errorPHP
<?php
// PHP 8+ with cURL. Save the payload as order.json.
$key = getenv('MEDIDENTA_CONSUMER_KEY');
$secret = getenv('MEDIDENTA_CONSUMER_SECRET');
if (!$key || !$secret) throw new RuntimeException('Configure API credentials');
$rawOrder = file_get_contents('order.json');
if ($rawOrder === false) throw new RuntimeException('Cannot read order.json');
json_decode($rawOrder, true, 512, JSON_THROW_ON_ERROR);
$ch = curl_init('https://hub.medidenta.com/api/orders.php');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $rawOrder,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => $key . ':' . $secret,
CURLOPT_HTTPHEADER => ['Accept: application/json', 'Content-Type: application/json'],
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 60,
]);
$raw = curl_exec($ch);
if ($raw === false) throw new RuntimeException(curl_error($ch));
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 400) throw new RuntimeException('HTTP ' . $status . ': ' . $data['code']);
echo $data['duplicate'] ? 'Already received' : 'Order queued';New order accepted
{
"success": true,
"message": "Order received and queued successfully.",
"status": "RECEIVED",
"source_id": 42,
"external_order_id": "123456",
"duplicate": false,
"request_timestamp": "2026-11-10T22:05:00Z"
}The illustrative source_id above will be replaced by the source assigned to your credentials. The returned status is the queue status.
Previously received order
{
"success": true,
"message": "Order was already received. No duplicate queue record was created.",
"status": "RECEIVED",
"source_id": 42,
"external_order_id": "123456",
"duplicate": true,
"request_timestamp": "2026-11-10T22:05:00Z"
}Retry behavior
- The combination of assigned source and external order ID identifies a received order.
- After a network failure or 500 response, retry with the same external order ID. Use a bounded retry policy with increasing delays.
- Both 201 with
duplicate: falseand 200 withduplicate: trueconfirm the order was received. - Resubmitting an existing ID is not an order-update operation. Contact Medidenta for corrections to an already received order.
- Inventory SKU scope restricts inventory reads; order intake uses source assignment and Write permission.
/api/orders-v2.php is also available and currently runs the same logic as /api/orders.php. Use /api/orders.php for the primary integration.
See errors and retries for validation codes and response statuses.