Skip to main content

Overview

The Orders API handles the creation and management of service orders. Orders connect clients with freelancers through purchased gig packages, integrating with YouCan Pay for payment processing.

Mutations

create

Create a new order for a gig package with payment information. Input Parameters:
amount
number
required
Order amount in MAD
transactionId
string
required
Payment transaction ID from payment provider
orderId
string
required
Unique order identifier
gigId
string
required
ID of the gig being purchased
packageId
string
required
ID of the specific package tier (basic, standard, or premium)
Note: This endpoint is currently a stub and requires implementation. Example:
await trpc.order.create.mutate({
  amount: 500,
  transactionId: "txn_abc123",
  orderId: "order_xyz789",
  gigId: "clxxx...",
  packageId: "pkg_clxxx..."
});

Order Model

Orders in the database follow this structure:

Order Fields

id
string
Unique order identifier (CUID)
userId
string
ID of the client placing the order
gigId
string
ID of the purchased gig
packageId
string
ID of the purchased package (basic, standard, or premium)
status
enum
Order status: pending, processing, completed, or cancelledDefault: pending
totalAmount
float
Total order amount in MAD
createdAt
DateTime
Order creation timestamp
updatedAt
DateTime
Last update timestamp

Relations

user
User
The client who placed the order
gig
Gig
The purchased gig
package
Package
The specific package tier purchased
payment
Payment
Associated payment record (one-to-one)

Payment Model

Payments associated with orders:

Payment Fields

id
string
Unique payment identifier (CUID)
orderId
string
Associated order ID (unique)
status
enum
Payment status: pending, success, or failedDefault: pending
amount
float
Payment amount in MAD
paymentMethod
string
Payment method used (e.g., “card”, “bank_transfer”)
transactionId
string
External transaction ID from payment provider
createdAt
DateTime
Payment creation timestamp
updatedAt
DateTime
Last update timestamp

Payment Integration

Khedma Market integrates with YouCan Pay for payment processing.

tokenizePayment()

Server-side function to tokenize a payment with YouCan Pay. Parameters:
  • amount (number): Payment amount
  • currency (string): Currency code (e.g., “MAD”)
  • order_id (string): Unique order identifier
Returns: Token object with ID for payment processing:
{
  token: {
    id: string // UUID token for payment
  }
}
Example Usage:
import { tokenizePayment } from "@/server/api/routers/order";

const tokenData = await tokenizePayment(
  500,      // amount in MAD
  "MAD",    // currency
  "order_123" // order ID
);

if (tokenData) {
  // Use tokenData.token.id for payment processing
  console.log("Payment token:", tokenData.token.id);
}

YouCan Pay API Flow

  1. Tokenize: Create a payment token
    POST https://youcanpay.com/api/tokenize
    Content-Type: multipart/form-data
    
    amount=500
    currency=MAD
    pri_key=pri_key_for_test
    order_id=12
    metadata[cart.id]=uuid
    metadata[type]=checkout
    
  2. Response: Receive token
    {
      "token": {
        "id": "26010885-fb7b-41eb-baf8-3420213f1ed5"
      }
    }
    
  3. Process: Use token to complete payment with YouCan Pay widget

Order Status Flow

pending → processing → completed

cancelled
  • pending: Order created, awaiting payment
  • processing: Payment confirmed, work in progress
  • completed: Order delivered and accepted
  • cancelled: Order cancelled by client or freelancer

Example: Complete Order Flow

// 1. Client selects a package
const gig = await getGigDetails("johndoe", "website-design");
const selectedPackage = gig.packages.basic;

// 2. Tokenize payment
const token = await tokenizePayment(
  selectedPackage.price,
  "MAD",
  `order_${Date.now()}`
);

// 3. Process payment with YouCan Pay (frontend)
// ... payment widget integration ...

// 4. Create order after successful payment
const order = await trpc.order.create.mutate({
  amount: selectedPackage.price,
  transactionId: paymentResponse.transactionId,
  orderId: `order_${Date.now()}`,
  gigId: gig.id,
  packageId: selectedPackage.id
});

console.log("Order created:", order.id);

Build docs developers (and LLMs) love