AgentSkillsCN

moyasar

为沙特阿拉伯集成 Moyasar 支付网关。涵盖 Web(托管表单、自定义 UI)、iOS、Android、Flutter 和 React Native 平台。支持信用卡、Mada、Apple Pay、Samsung Pay 以及 STC Pay 等支付方式。适用于构建结账流程、支付处理系统,或生成支付链接时使用。

SKILL.md
--- frontmatter
name: moyasar
description: Integrate Moyasar payment gateway for Saudi Arabia. Covers web (hosted form, custom UI), iOS, Android, Flutter, React Native. Supports cards, Mada, Apple Pay, Samsung Pay, STC Pay. Use when building checkout, payment processing, or payment links.

Moyasar Payments

Saudi Arabia's primary payment gateway.

Core Rules

Amounts: Always in halalas (1 SAR = 100 halalas). Minimum: 100.

API Keys:

KeyPrefixUse
Publishablepk_test_ / pk_live_Client-side only
Secretsk_test_ / sk_live_Server-side only

Payment Statuses: initiatedpaid | failed | authorizedcapturedrefunded | voided

Handling Failed Payments

When status === 'failed', check source.message and source.response_code:

CodeReason
14Invalid Card Number
51Insufficient Funds
54Expired Card
55Incorrect PIN
82CVV Validation Error
96System Error

See errors.md for full error list with English/Arabic translations.

The Trust Problem

Never trust the client. After payment, Moyasar redirects to your callback_url with status. But users can manipulate URLs, close browsers, or have network issues.

Verification Flow

code
┌─────────────────────────────────────────────────────────────────┐
│  CLIENT                           SERVER                        │
│                                                                 │
│  1. User pays via Moyasar ───────────────────────────────────►  │
│                                                                 │
│  2. Redirect to callback_url?id=xxx&status=paid                 │
│     → Show success/failure message (OK for UX)                  │
│     → But do NOT grant access or confirm purchase yet           │
│                                                                 │
│                                   3. VERIFY before fulfilling:  │
│                                      Option A: Fetch payment    │
│                                      Option B: Webhook          │
│                                                                 │
│  4. Grant access / confirm  ◄────────────────────────────────   │
│     only after server verifies                                  │
└─────────────────────────────────────────────────────────────────┘

Option A - Fetch Payment (simpler, synchronous):

javascript
// On callback, verify with Moyasar API
const payment = await fetch(`https://api.moyasar.com/v1/payments/${id}`, {
  headers: { 'Authorization': `Basic ${btoa(process.env.MOYASAR_SECRET_KEY + ':')}` }
}).then(r => r.json());

if (payment.status === 'paid' && payment.amount === expectedAmount) {
  // Safe to fulfill
}

Option B - Webhooks (recommended for reliability):

  • Moyasar POSTs to your server when payment status changes
  • Retries on failure (1min → 10min → 30min → 1hr → 2hr)
  • See webhooks.md

Platform Guide

Web Applications

See web.md for complete guide.

Two approaches:

ApproachUse When
Hosted FormQuick integration, PCI compliance handled
Custom UINeed full design control, willing to handle tokenization

Quick start (Hosted Form):

html
<script src="https://cdn.moyasar.com/mpf/1.14.0/moyasar.js"></script>
<link rel="stylesheet" href="https://cdn.moyasar.com/mpf/1.14.0/moyasar.css">
<div class="mysr-form"></div>
<script>
Moyasar.init({
  element: '.mysr-form',
  amount: 10000,
  currency: 'SAR',
  description: 'Order #123',
  publishable_api_key: process.env.MOYASAR_PUBLISHABLE_KEY,
  callback_url: 'https://yoursite.com/callback',
  methods: ['creditcard', 'applepay', 'stcpay'],
  metadata: { order_id: '123' }  // Link payment to your order
});
</script>

Mobile Applications

PlatformReferencePackage
iOSios.mdMoyasarSdk (SPM/CocoaPods)
Androidandroid.mdcom.github.Moyasar:moyasar-android-sdk
Flutterflutter.mdmoyasar (pub.dev)
React Nativereact-native.mdreact-native-moyasar-sdk

Server-Side Operations

See api.md for:

  • Verify payments
  • Refunds (full/partial)
  • Capture/void (pre-auth)
  • Tokenization (save cards)
  • Invoices (payment links)

Reference Files

FileWhen to Read
web.mdBuilding web checkout (hosted form, custom UI, Apple Pay, STC Pay)
ios.mdiOS app integration
android.mdAndroid app integration
flutter.mdFlutter app integration
react-native.mdReact Native app integration
api.mdServer-side operations (verify, refund, capture, tokens, invoices)
webhooks.mdSetting up payment webhooks
errors.mdError codes with English/Arabic translations
test-data.mdTest cards, STC Pay Testing, Apple Pay Testing

Key Gotchas

  1. Always use metadata - Include order_id to link payment back to your system
  2. Webhook secret is in BODY, not header - Moyasar sends secret_token in request body
  3. Idempotency - Use given_id (UUID) when creating payment to prevent duplicate charges on retry
  4. Apple Pay needs domain verification - Host file at /.well-known/apple-developer-merchantid-domain-association