CareerByteCode

ByteConnect developer guide

For developers at CareerByteCode ByteConnect partners (ByteConnect Link: the API tier). Your buyer always pays on CareerByteCode's own secure checkout; your server lists programs, makes checkout links and follows the orders. Partners: the same guide, with your own key id and catalogue in the examples, is in your partner console.

How ByteConnect works

ByteConnect Link lets your website sell CareerByteCode programs. Your server lists what you may sell, makes a checkout link for each buyer, and follows the order. The buyer always pays on CareerByteCode's own secure checkout, so you never handle card or UPI details.

  1. List what you may sell: GET catalogue (prices, product details).
  2. Sell: POST checkout returns a checkout_url; send your buyer there.
  3. Buyer pays on CareerByteCode (Google sign-in, Razorpay). The program is unlocked for them automatically.
  4. You are told: an order notification reaches your server; GET orders shows the status any time.
  5. Your share is booked as a ByteStore reseller share and paid with your ByteStore earnings, after 10 percent TDS.

Go-live checklist

You start in sandbox with a test key. CareerByteCode switches you to live when every line of the checklist in your console is ticked: partner agreement signed, payout KYC verified, linked to a ByteStore (its reseller rate applies), at least one product type allowed, at least one server address listed, and a signed test call answered 200 with your test key (partners outside India: also a country that is allowed).

Base address: https://www.careerbytecode.in/api/v1/ (https only). Every answer is JSON: {"ok":true,"data":{...},"request_id":"req_..."}.

Keys, modes and addresses

  • Test keys start with cbc_test_: sandbox orders, no payment. Live keys start with cbc_live_ and work only from your registered server addresses.
  • Each key has a secret (48 hex characters) shown once, when CareerByteCode gives you the key. Keep it on your server: never in a browser, an app or a web address.
  • Rate limit: 60 requests a minute per key (agreed with you).
  • Keys can be rotated: the new key works at once and the old one keeps working for 7 days. Ask CareerByteCode for a rotation or a new key.
  • Server addresses change only through a request in your console (how), never by email.

Signing requests

Every request carries four headers. The signature is HMAC-SHA256 with your secret over five lines joined by a newline:

X-CBC-Key:       cbc_test_xxxxxxxxxxxx
X-CBC-Timestamp: 1791360000          unix seconds, within 5 minutes of our clock
X-CBC-Nonce:     6f1c2b9e0a7d4c11     new for every request, 8-64 of A-Z a-z 0-9 _ -
X-CBC-Signature: hex HMAC_SHA256(secret,
                   METHOD + "\n" + PATH_AND_QUERY + "\n" + TIMESTAMP + "\n" + NONCE + "\n" + sha256_hex(BODY))

METHOD in capitals. PATH_AND_QUERY is exactly what you request, for example /api/v1/catalogue?type=course. BODY is the raw body you send (empty for GET). Never put the key or the secret in the address: that is refused with key_in_url.

function cbc_call(string $method, string $pathQuery, string $body, string $key, string $secret): array {
    $ts = (string)time(); $nonce = bin2hex(random_bytes(8));
    $sts = strtoupper($method) . "\n" . $pathQuery . "\n" . $ts . "\n" . $nonce . "\n" . hash('sha256', $body);
    $ch = curl_init('https://www.careerbytecode.in' . $pathQuery);
    curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => $body !== '' ? $body : null,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-CBC-Key: ' . $key, 'X-CBC-Timestamp: ' . $ts, 'X-CBC-Nonce: ' . $nonce,
                               'X-CBC-Signature: ' . hash_hmac('sha256', $sts, $secret)]]);
    $res = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
    return [$code, json_decode((string)$res, true)];
}
// [$code, $json] = cbc_call('GET', '/api/v1/catalogue', '', 'cbc_test_xxxxxxxxxxxx', getenv('CBC_SECRET'));

Sandbox testing

With a test key every order is a sandbox order. Its checkout_url opens a test page with Simulate a successful payment and Simulate a refund. Your server receives the same notifications as for a real order. Nothing is charged or booked.

  1. Call GET ping with your test key: it must answer 200 (this ticks the signed-test line of the checklist).
  2. Read the catalogue, make a checkout, open the link and simulate a payment.
  3. Check that your server got order.paid and that GET orders shows paid.
  4. Simulate a refund and check order.refunded.

GET ping

Checks your key, signature and server address. Answers your partner name, mode, status, scopes, products, the address we saw, our time and your rate limit.

GET /api/v1/ping

200 {"ok":true,"data":{"partner":"Your company","mode":"test","status":"sandbox","scopes":["ping","catalogue","checkout","orders"],
  "products":["course"],"your_ip":"203.0.113.10","server_time":1791360000,"rate_per_min":60},"request_id":"req_..."}

GET catalogue

The programs you may sell right now: what your ByteStore resells, limited to the product types agreed with you. Optional ?type=course|exam|byteclass|byteplay|bytelabs.

GET /api/v1/catalogue

200 {
    "ok": true,
    "data": {
        "currency": "INR",
        "gst_pct": 18,
        "items": [
            {
                "id": "course:kubernetes-bootcamp",
                "type": "course",
                "ref": "kubernetes-bootcamp",
                "title": "Kubernetes Bootcamp",
                "base_inr": 9999,
                "gst_inr": 1800,
                "total_inr": 11799,
                "summary": "Hands-on Kubernetes from pods to production.",
                "highlights": [
                    "Live instructor-led program",
                    "Hands-on labs and real projects"
                ],
                "image": "https://www.careerbytecode.in/assets/img/brand/logo.png",
                "creator": "CareerByteCode",
                "detail_url": "https://www.careerbytecode.in/courses/kubernetes-bootcamp/"
            }
        ]
    },
    "request_id": "req_..."
}
FieldMeaning
idWhat you send to POST checkout as item.
base_inr, gst_inr, total_inrPrice before GST, 18 percent GST, total. Show the total including GST.
summary, highlightsWhat the offering is and what the buyer gets (a list). Show them on your product page.
image, creatorA picture (https, may be empty) and who runs it.
detail_urlThe public product page, for reading only: a sale counts for you only when the buyer pays through your checkout_url.

Prices change only on our side; read the catalogue at least once a day. New fields may be added later; ignore any field you do not use.

POST checkout

Makes an order and returns the checkout link to send your buyer to. Body: {"item":"course:kubernetes-bootcamp","partner_ref":"A-1001"}. partner_ref is your own order number (up to 64 of letters, digits, . : - _).

Send X-CBC-Idempotency-Key (8-80 characters, unique per order on your side): if your request is retried, you get the same order back instead of a second one.

POST /api/v1/checkout
X-CBC-Idempotency-Key: A-1001-try1

{"item":"course:kubernetes-bootcamp","partner_ref":"A-1001"}

201 {"ok":true,"data":{"order":{"id":"9f2c...","status":"created","mode":"test","item":"course:kubernetes-bootcamp",
  "title":"Kubernetes Bootcamp","base_inr":9999,"gst_inr":1800,"total_inr":11799,"partner_ref":"A-1001",
  "checkout_url":"https://www.careerbytecode.in/api/go.php?t=9f2c...","created_at":1791360000,"expires_at":1791532800}},"request_id":"req_..."}

Redirect the buyer to checkout_url within 48 hours. They sign in with Google on CareerByteCode and pay there.

GET orders

Your orders for the key's mode, newest first. Optional ?status=created|paid|refunded|expired and &limit=1-200. A single order by its id: GET /api/v1/orders/{id}.

StatusMeaning
createdLink made, not yet paid.
paidThe buyer paid; paid_inr and paid_at are set.
refundedFully refunded; refunded_at is set.
expiredNot paid within 48 hours.

GET ip-check

To add, remove or move your server addresses, open Server addresses in your console:

  1. Send a request: the change, the new public address(es) (a range no wider than /24, or /48 for IPv6), the reason, the hosting provider, when to switch, how long the old addresses keep working (0, 1, 3 or 7 days), and a proof (hosting invoice or provider screenshot showing the address).
  2. Enter the 6-digit code we email to your contact email. Only then does the request reach CareerByteCode.
  3. Optional but faster: from the NEW server, make one normally signed GET /api/v1/ip-check with your key. While your confirmed request is open, this one endpoint is answered from the new address and we record it as proof. It answers your_ip, on_whitelist and recorded_for_request.
  4. We approve, ask for more information (you reply and upload in the console) or reject. You get an email at every step; approved changes switch now or on your date, and the old addresses are removed after the overlap.

Emergency: a leaked or retired server can be removed at once from the console without review (it only reduces access). Adding an address back needs a normal request.

Order notifications (webhooks)

Set your https address in your console. We POST JSON for order.paid, order.refunded and webhook.test:

POST https://your-site.example/cbc-webhook
X-CBC-Event: order.paid
X-CBC-Delivery: 1234
X-CBC-Timestamp: 1791360420
X-CBC-Signature: hex HMAC_SHA256(webhook_secret, TIMESTAMP + "." + RAW_BODY)

{"id":"evt_...","event":"order.paid","created":1791360420,"data":{"order":{ ...same as GET /orders/{id}... }}}

Check the signature with your webhook secret (it starts with whsec_), refuse timestamps older than 5 minutes, then answer any 2xx within 6 seconds. Use data.order.id to ignore a notification you already handled. If we do not get a 2xx we retry after 5 minutes, 15 minutes, 1, 3, 12 and 24 hours (7 tries).

$raw = file_get_contents('php://input'); $ts = $_SERVER['HTTP_X_CBC_TIMESTAMP'] ?? '';
$ok = abs(time() - (int)$ts) <= 300
   && hash_equals(hash_hmac('sha256', $ts . '.' . $raw, $webhookSecret), $_SERVER['HTTP_X_CBC_SIGNATURE'] ?? '');
if (!$ok) { http_response_code(401); exit; }
http_response_code(200); // then handle json_decode($raw, true)['data']['order'] once per order id

Errors and limits

Every error answers {"ok":false,"error":{"code":"...","message":"..."},"request_id":"req_..."}. Quote the request id when you contact us.

StatusCodes
400key_in_url, bad_json, unknown_item, bad_partner_ref, bad_type, bad_status, bad_idempotency_key
401missing_key, unknown_key, key_revoked, key_expired, bad_timestamp, bad_nonce, bad_signature, nonce_reused
403https_required, partner_paused, partner_not_active, ip_not_allowed, scope_missing
404not_found, unknown_order
409idempotency_conflict
429rate_limited (see Retry-After; 60 a minute per key)
503rate_unavailable (try again shortly)

Activity, CSV and statements

  • Activity (console): calls per day (allowed, refused, errors), endpoints with average time, why calls were refused with a hint for each reason, and sales per product family with conversion and your share.
  • CSV: your own calls (up to 90 days) and orders, from calls and orders (signed in).
  • Monthly statement: emailed on the 1st of every month to your contact email: links, paid orders, refunds and your share for the month.

OpenAPI file

A machine-readable description of every endpoint (OpenAPI 3.0), for Postman, Insomnia or a code generator: /byteconnect/openapi.php.

Tools cannot make our signature on their own: add the four X-CBC headers with a pre-request script (see Signing requests).

What's new

  • 7 Oct 2026 New addresses under /byteconnect/
    Your console is now /byteconnect/console.php, this guide /byteconnect/docs/, the CSV downloads /byteconnect/export.php and the OpenAPI file /byteconnect/openapi.php. The old /api-partners/ addresses redirect permanently, so bookmarks keep working. The API itself (/api/v1/) and checkout links did not change. Read more
  • 7 Oct 2026 Guide inside your console
    The full developer guide now sits in your partner console menu with your own key id, mode, server addresses and a real catalogue item in the examples. Python and cURL samples added; OpenAPI file available. Read more
  • 7 Oct 2026 Product details in the catalogue
    Every catalogue item also carries summary, highlights, image, creator and detail_url, so your site can show what the offering is before checkout. Existing fields are unchanged. Read more
  • 7 Oct 2026 Activity, CSV and monthly statements
    Your console shows calls per day, endpoints, refusal reasons with hints and sales per product family, with CSV downloads of your own calls and orders. A statement is emailed on the 1st of every month. Read more
  • 7 Oct 2026 Server address change requests
    Add, remove or replace server addresses from your console with an email code, proof and review; optional signed GET /api/v1/ip-check from the new server; emergency removal. Read more
  • 7 Oct 2026 Selling through the API
    GET /api/v1/catalogue, POST /api/v1/checkout, GET /api/v1/orders, signed order notifications (webhooks) and the sandbox. Read more
  • 7 Oct 2026 ByteConnect API opened
    Signed requests (key, timestamp, nonce, HMAC-SHA256), test and live keys, server address whitelist, rate limit and GET /api/v1/ping. Read more

Help and contact

  • Quote the request_id of the answer you are asking about.
  • Email: support@careerbytecode.in
  • Keys, rotations and go-live: ask CareerByteCode; server addresses: request them in your console.
  • Never send a secret by email or chat. We will never ask for it.