@raba7ni/raba7ni
v2.1.1
Published
Official SDK for the Raba7ni Platform Developer API - Loyalty, Cashback & Coins
Downloads
31
Readme
@raba7ni/raba7ni v2.1.1
Official TypeScript SDK for the Raba7ni Platform Developer API.
What's New in v2.0
- Product-based API structure - Separate endpoints for Loyalty, Cashback, and Coins
- Internal member token management - Automatic token handling after authentication
- Points & Stamps operations - Earn, redeem, balance, and history
- Cashback operations - Full cashback earn/redeem workflow
- Coins operations - Wallet management, issue/spend coins
- Member authentication - OTP-based auth for customer-facing apps
Installation
npm install @raba7ni/raba7niQuick Start
import { Raba7niSDK } from "@raba7ni/raba7ni";
const sdk = new Raba7niSDK({
appId: "app_your_app_id",
apiKey: "dev_your_api_key",
});
// Test connection
const scopes = await sdk.testConnection();
console.log("Connected! Scopes:", scopes.scopes);
// Earn points for a member (identify by phone, email, or memberId)
const result = await sdk.earnPoints(5, 25.0, { phone: "+21612345678" });
console.log("Points earned:", result.points_earned);Configuration
| Option | Type | Default | Description |
| ------------ | -------- | ------------------------- | ----------------------------------- |
| appId | string | required | Application ID (starts with app_) |
| apiKey | string | required | API Key (starts with dev_) |
| baseUrl | string | https://app.raba7ni.com | API base URL |
| timeout | number | 30000 | Request timeout (ms) |
| maxRetries | number | 3 | Max retry attempts |
| retryDelay | number | 1000 | Initial retry delay (ms) |
Member Authentication
Many operations (redemptions, wallet access) require member authentication. The SDK handles token storage internally.
Member Management
// Check if a member exists (by email or phone)
const check = await sdk.checkMember({ email: "[email protected]" });
// or: await sdk.checkMember({ phone: "+21612345678" });
if (check.exists) {
console.log("Member found:", check.member);
}
// Register a new member
const newMember = await sdk.registerMember({
name: "John Doe",
email: "[email protected]",
phone: "+21612345678",
});Request & Verify OTP
// Step 1: Request OTP (sent to member's email or phone)
await sdk.requestMemberOTP({ email: "[email protected]" });
// or: await sdk.requestMemberOTP({ phone: '+21612345678' });
// Step 2: Verify OTP (token stored internally)
const auth = await sdk.verifyMemberOTP({
email: "[email protected]",
code: "123456",
});
console.log("Authenticated as:", auth.member.name);
// Now authenticated endpoints will work automatically
const wallet = await sdk.getWallet();Token Management
// Check if authenticated
if (sdk.isAuthenticated()) {
// Can use authenticated endpoints
}
// Manually set token (e.g., from stored session)
sdk.setMemberToken("token_abc123", "2025-12-31T23:59:59Z");
// Clear token (logout)
sdk.clearMemberToken();
// or
await sdk.logoutMember(); // Also invalidates on serverLoyalty API
Points
// Earn points from purchase - identify member by phone, email, or memberId
const earn = await sdk.earnPoints(cardId, 25.0, { phone: "+21612345678" }, {
staff_identifier: "staff_001",
note: "Coffee purchase",
reference: "ORDER-123",
});
console.log("Earned:", earn.points_earned, "New balance:", earn.new_balance);
console.log("Is new member:", earn.is_new_member);
// Identify by email instead
const earn2 = await sdk.earnPoints(cardId, 50.0, { email: "[email protected]" });
// Identify by member ID
const earn3 = await sdk.earnPoints(cardId, 30.0, { memberId: 123 });
// Get balance
const balance = await sdk.getPointsBalance(cardId, "+21612345678");
console.log("Current points:", balance.balance);
// Get history
const history = await sdk.getPointsHistory(cardId, "+21612345678", {
limit: 20,
offset: 0,
});
// Refund points (for returns/cancellations)
const refund = await sdk.refundPoints(cardId, 25.0, { phone: "+21612345678" }, {
points_to_deduct: 50,
reference: "REFUND-123",
});
console.log("Points deducted:", refund.points_deducted);
// Redeem points (requires authentication)
await sdk.verifyMemberOTP({ email: "[email protected]", code: "123456" });
const redeem = await sdk.redeemPoints(cardId, rewardId);
console.log("Redeemed reward:", redeem.reward.name);Stamps
// Add stamps
const stamp = await sdk.addStamps(cardId, "+21612345678", 1);
console.log("Stamps:", stamp.new_balance, "/", stamp.stamps_required);
// Get balance
const balance = await sdk.getStampsBalance(cardId, "+21612345678");
// Redeem stamps (requires authentication)
const redeem = await sdk.redeemStamps(cardId, rewardId);Cards & Rewards
// List available cards
const { cards } = await sdk.listCards();
// Get card details
const card = await sdk.getCardInfo(cardId);
// Get rewards for a card
const { rewards } = await sdk.listCardRewards(cardId);Claims
// Request claim OTP
await sdk.requestClaimOTP("[email protected]", cardId, rewardId);
// Create claim request
const { claim_request } = await sdk.createClaimRequest({
member_email: "[email protected]",
card_id: cardId,
reward_id: rewardId,
verification_code: "123456",
member_note: "Please deliver to office",
});
// Approve/Reject (staff operations)
await sdk.approveClaimRequest(claim_request.id, "Approved!");
await sdk.rejectClaimRequest(claim_request.id, "Out of stock");Referrals
// Get stats
const stats = await sdk.getReferralStats(cardId);
// Validate code
const result = await sdk.validateReferralCode("REF123ABC", cardId);
if (result.is_valid) {
console.log("Referred by:", result.referrer?.name);
}
// Apply referral
await sdk.applyReferral("REF123ABC", cardId, "[email protected]");Cashback API
// Earn cashback from purchase - identify member by phone, email, or memberId
const earn = await sdk.earnCashback(cardId, 100.0, { phone: "+21612345678" }, {
reference: "ORDER-123",
});
console.log(
"Cashback earned:",
earn.cashback_earned,
"(",
earn.cashback_percentage,
"%)"
);
console.log("Is new member:", earn.is_new_member);
// Identify by email instead
const earn2 = await sdk.earnCashback(cardId, 50.0, { email: "[email protected]" });
// Get balance
const balance = await sdk.getCashbackBalance(cardId, "+21612345678");
// Get history
const history = await sdk.getCashbackHistory(cardId, "+21612345678");
// Refund cashback (for returns/cancellations)
const refund = await sdk.refundCashback(cardId, 50.0, { phone: "+21612345678" }, {
cashback_to_deduct: 2.5,
reference: "REFUND-123",
});
console.log("Cashback deducted:", refund.cashback_deducted);
// Redeem cashback (requires authentication + PIN)
await sdk.verifyMemberOTP({ email: "[email protected]", code: "123456" });
const redeem = await sdk.redeemCashback(cardId, 10.0, "1234");
// List cashback cards
const { cards } = await sdk.listCashbackCards();Coins API
Wallet Operations (Authenticated)
// Must authenticate first
await sdk.verifyMemberOTP({ email: "[email protected]", code: "123456" });
// Get wallet balance
const wallet = await sdk.getWallet();
console.log("Coins:", wallet.wallet.coin_balance);
console.log("Value in TND:", wallet.wallet.balance_in_tnd);
// Get QR code for receiving coins (requires PIN setup)
const qr = await sdk.getWalletQR();
console.log("QR Data:", qr.qr_data);
// Get transaction history
const history = await sdk.getWalletHistory({ limit: 50 });Coin Operations
// Issue coins to member (from purchase) - identify by phone, email, or memberId
const issue = await sdk.issueCoins(clubId, 50.0, { phone: "+21612345678" }, {
campaign_id: 5,
reference: "ORDER-123",
});
console.log("Coins issued:", issue.coins_issued);
console.log("Campaign bonus:", issue.campaign_bonus);
console.log("Is new member:", issue.is_new_member);
// Identify by email instead
const issue2 = await sdk.issueCoins(clubId, 30.0, { email: "[email protected]" });
// Refund coins (for returns/cancellations)
const refund = await sdk.refundCoins(clubId, 50.0, { phone: "+21612345678" }, {
coins_to_deduct: 25,
reference: "REFUND-123",
});
console.log("Coins deducted:", refund.coins_deducted);
// Spend coins (requires authentication + PIN)
await sdk.verifyMemberOTP({ email: "[email protected]", code: "123456" });
const spend = await sdk.spendCoins(clubId, 100, "1234");
console.log("Spent:", spend.coins_spent, "= TND", spend.amount_in_tnd);
// List participating clubs
const { clubs } = await sdk.listCoinsClubs();
// List active campaigns
const campaigns = await sdk.listCoinsCampaigns(clubId);Webhook Handling
import { WebhookHandler } from "@raba7ni/raba7ni";
const handler = new WebhookHandler("your_webhook_secret");
// Express example
app.post("/webhooks", async (req, res) => {
const signature = req.headers["x-webhook-signature"] as string;
const payload = JSON.stringify(req.body);
try {
await handler.handleWebhook(payload, signature, {
onMemberJoined: async (data) => {
console.log("New member:", data.member.name);
},
onClaimRequestCreated: async (data) => {
console.log("New claim:", data.claim_request.id);
},
onClaimRequestProcessed: async (data) => {
console.log("Claim processed:", data.status);
},
});
res.status(200).send("OK");
} catch (error) {
res.status(400).send("Invalid webhook");
}
});Error Handling
import {
Raba7niError,
AuthenticationError,
RateLimitError,
ValidationError,
MemberTokenRequiredError,
} from "@raba7ni/raba7ni";
try {
await sdk.redeemPoints(5, 10);
} catch (error) {
if (error instanceof MemberTokenRequiredError) {
console.error("Please authenticate first");
} else if (error instanceof AuthenticationError) {
console.error("Invalid credentials");
} else if (error instanceof RateLimitError) {
console.error("Rate limited, retry after:", error.retryAfter);
} else if (error instanceof ValidationError) {
console.error("Validation errors:", error.validationErrors);
} else if (error instanceof Raba7niError) {
console.error("API error:", error.message, error.code);
}
}Rate Limiting
const info = sdk.getRateLimitInfo();
console.log("Hourly remaining:", info.hourlyRemaining);
console.log("Daily remaining:", info.dailyRemaining);Utilities
import {
normalizePhoneNumber,
validateEmail,
validateCardId,
} from "@raba7ni/raba7ni";
normalizePhoneNumber("+1 (555) 123-4567"); // '+15551234567'
validateEmail("[email protected]"); // true
validateCardId("5"); // 5 (number)TypeScript Types
All types are exported:
import type {
Member,
Card,
Reward,
EarnPointsResponse,
WalletResponse,
CoinCampaign,
// ... and many more
} from "@raba7ni/raba7ni";Migration from v1.x
Breaking Changes
- Legacy methods removed:
getMemberDetails(),findOrCreateMember()- use product-specific endpoints - New auth flow: Use
requestMemberOTP()+verifyMemberOTP()for member auth - Internal token storage: Token is stored in SDK after
verifyMemberOTP()
Migration Examples
// v1.x
const details = await sdk.getMemberDetails(cardId, phone);
// v2.0
const balance = await sdk.getPointsBalance(cardId, phone);
// or for authenticated member data:
await sdk.verifyMemberOTP({ phone, code: "123456" });
const profile = await sdk.getMemberProfile();Requirements
- Node.js 18+
- TypeScript 5.0+ (for TypeScript users)
Support
- Documentation: https://app.raba7ni.com/en-us/docs
License
MIT © Raba7ni
