alipay_serverpod
Serverpod integration for Alipay App Pay + QR Pay.
Prerequisites
Before using this package, you need to complete the following steps on Alipay platforms.
Step 1: Register Alipay Merchant Account
- Go to Alipay Merchant Platform
- Register a merchant account (requires business license for enterprise, or personal real-name for individual)
- Complete account verification
Step 2: Sign Product Agreements
Sign the required payment products at Alipay Merchant Platform - Product Center:
| Feature | Product to Sign | Notes |
|---|---|---|
| App Pay | App Payment (App支付) | For invoking Alipay app from your mobile app |
| QR Pay | Face-to-Face Payment (当面付) | For generating QR codes |
Note: Product approval may take 1-3 business days.
Step 3: Create Application on Open Platform
- Go to Alipay Open Platform Console
- Click Create Application → Select Mobile/Web App
- Fill in basic information and submit for review
- After approval, note down your App ID
Step 4: Configure Keys
- In your application page, go to Development Settings → Interface Signing Method
- Choose Self-upload Public Key mode
- Generate RSA2 key pair (2048-bit):
# Generate a PKCS#8 private key (BEGIN PRIVATE KEY)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem
# Export public key
openssl pkey -in private_key.pem -pubout -out public_key.pem
# Get public key string (upload this to Alipay)
grep -v "^-----" public_key.pem | tr -d '\n' && echo
- Upload the public key string to Alipay console
- Download the Alipay Public Key (支付宝公钥) from console after upload
- Save the PKCS#8 PEM (
private_key.pem, includingBEGIN PRIVATE KEY/END PRIVATE KEY) forpasswords.yaml. Do not convert it to PKCS#1.
Official Docs: Key Configuration Guide
Step 5: Bind Products to Application
- In your application page, go to Product bindng (产品绑定)
- Add the products you signed in Step 2
Features
- Config Integration - Read sensitive keys from
passwords.yaml, keep non-sensitive config inserver.dart - Base Endpoint - Ready-to-use
AlipayPaymentBaseEndpointhelpers - Notify Route - Signature verification and callback injection
- Full Export - Re-exports all APIs from
alipay
Installation
# server/pubspec.yaml
dependencies:
alipay_serverpod: ^0.2.0
Configuration
passwords.yaml (credentials only)
shared:
alipayRsa2PrivateKey: |
-----BEGIN PRIVATE KEY-----
...your private key...
-----END PRIVATE KEY-----
alipayPublicKey: 'MIIBIjANBg...' # Alipay public key; loaded as publicKeyBase64
server.dart (non-sensitive config)
import 'package:alipay_serverpod/alipay_serverpod.dart';
void run(List<String> args) async {
final pod = Serverpod(args, Protocol(), Endpoints());
AlipayServerpodConfigStore.configure(
appConfig: AlipayAppConfigServerpod(
appId: 'your-alipay-app-id',
notifyUrl: 'https://your-server/alipay/notify',
),
);
// publicKeyBase64 is required. It is loaded from alipayPublicKey.
final alipayConfig = AlipayConfigServerpod.fromServerpod(pod);
pod.webServer.addRoute(
AlipayNotifyRoute(
config: alipayConfig,
onPaymentSuccess: (session, notification) async {
// Your idempotent recharge logic here
},
),
'/alipay/notify',
);
await pod.start();
}
Quick Start
AlipayServerpodConfig.publicKeyBase64 is required. fromSession and fromServerpod fill it from alipayPublicKey (Alipay public key, Base64 SubjectPublicKeyInfo, not a PEM). QR precreate and query always verify the gateway response with that key. The notify route uses the same key, rejects a missing or mismatched app_id, rejects a blank total_amount, and restores + in the signature before verification.
Using Base Endpoint
import 'package:alipay_serverpod/alipay_serverpod.dart';
class PaymentEndpoint extends AlipayPaymentBaseEndpoint {
Future<AppPayOrder> createOrder(Session session, int amountCents) async {
return createAppPayOrder(
session,
amountCents,
outTradeNo: 'order_001',
subject: 'Recharge',
passbackParams: 'uid=123',
);
}
}
Notify Callback (Idempotent)
AlipayNotifyRoute(
config: alipayConfig,
onPaymentSuccess: (session, notification) async {
if (!notification.paid) return;
// Idempotent logic recommended
// 1) Check existing transaction by outTradeNo
// 2) If not exists, apply balance change
},
);
API Reference
AlipayServerpodConfigStore
Global config store for non-sensitive values.
AlipayServerpodConfigStore.configure(
appConfig: AlipayAppConfigServerpod(...),
);
AlipayConfigServerpod
Builds AlipayServerpodConfig by combining config + passwords.
AlipayPaymentBaseEndpoint
Base endpoint with helper methods:
createAppPayOrdercreateQrOrderqueryOrder
AlipayNotifyRoute
Signature-verified notify route with injected callbacks.
AlipayNotification
Parsed notify payload with helper fields:
paideffectiveAmount
Troubleshooting
| Issue | Error Code | Cause | Fix |
|---|---|---|---|
| Missing passwords | - | Keys not in passwords.yaml |
Add alipayRsa2PrivateKey and alipayPublicKey |
| Invalid signature | isv.invalid-signature / 40002 |
Private key doesn't match public key on Alipay | Re-upload public key to Alipay console, ensure private key matches |
| Insufficient permissions | isv.insufficient-isv-permissions / 40006 |
Product not signed or not bound | Sign product at Merchant Platform, bind to app at Open Platform |
| App ID not found | isv.invalid-app-id |
Wrong App ID or app not approved | Check App ID, ensure app status is "Online" |
| Notify not triggered | - | URL unreachable | Ensure HTTPS with valid certificate, public network access |
| Base64 decode error | FormatException: Invalid padding |
Extra characters in private key | Remove trailing whitespace/newlines from key string |
Common Configuration Errors
1. Key Mismatch (isv.invalid-signature)
The most common error. Verify your keys match:
# Export the public key from the PKCS#8 PEM
openssl pkey -in private_key.pem -pubout
# Compare with the public key on the Alipay console - they must be identical
2. Product Not Bound (40006)
- Check Merchant Platform → Products → Ensure product is signed
- Check Open Platform → Your App → Product Binding → Ensure product is added
3. Wrong Key Format
alipayRsa2PrivateKey: PKCS#8 PEM (-----BEGIN PRIVATE KEY-----…-----END PRIVATE KEY-----). Not PKCS#1 (-----BEGIN RSA PRIVATE KEY-----).alipayPublicKey: Alipay public key from the console, Base64 SubjectPublicKeyInfo (NOT your own public key)
Related Packages
License
MIT License
Libraries
- alipay_serverpod
- Alipay Serverpod integration.