packwise-skills 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.cursorrules +23 -23
  2. package/CLAUDE.md +25 -25
  3. package/LICENSE +21 -0
  4. package/README.md +404 -295
  5. package/audit.md +224 -224
  6. package/bin/packwise.js +322 -155
  7. package/install.sh +123 -0
  8. package/package.json +32 -31
  9. package/skill.md +944 -719
  10. package/sub-skills/ai/local-llm.md +183 -183
  11. package/sub-skills/ai/python-ml.md +164 -164
  12. package/sub-skills/backend/go-server.md +184 -184
  13. package/sub-skills/backend/java-spring.md +241 -241
  14. package/sub-skills/backend/node-server.md +164 -164
  15. package/sub-skills/backend/php-laravel.md +175 -175
  16. package/sub-skills/backend/python-server.md +164 -164
  17. package/sub-skills/backend/rust-backend.md +118 -118
  18. package/sub-skills/cli/python-cli.md +236 -236
  19. package/sub-skills/cli/sdk-library.md +497 -497
  20. package/sub-skills/cloud/ci-cd-pipelines.md +350 -350
  21. package/sub-skills/cloud/docker.md +191 -191
  22. package/sub-skills/cloud/kubernetes.md +277 -277
  23. package/sub-skills/cloud/payment-integration.md +307 -307
  24. package/sub-skills/cross-platform/multiplatform.md +252 -252
  25. package/sub-skills/desktop/electron.md +783 -783
  26. package/sub-skills/desktop/game-dev.md +443 -443
  27. package/sub-skills/desktop/native-app.md +123 -123
  28. package/sub-skills/desktop/scenarios.md +443 -443
  29. package/sub-skills/desktop/smart-platforms.md +324 -324
  30. package/sub-skills/desktop/tauri.md +428 -428
  31. package/sub-skills/desktop/vr-ar.md +252 -252
  32. package/sub-skills/desktop/web-to-desktop.md +153 -153
  33. package/sub-skills/embedded/car-infotainment.md +129 -129
  34. package/sub-skills/embedded/esp32.md +184 -184
  35. package/sub-skills/embedded/ros.md +150 -150
  36. package/sub-skills/embedded/stm32.md +160 -160
  37. package/sub-skills/mobile/android.md +322 -322
  38. package/sub-skills/mobile/capacitor.md +232 -232
  39. package/sub-skills/mobile/flutter-mobile.md +138 -138
  40. package/sub-skills/mobile/harmonyos.md +150 -150
  41. package/sub-skills/mobile/ios.md +245 -245
  42. package/sub-skills/mobile/react-native.md +443 -443
  43. package/sub-skills/mobile/wearables.md +230 -230
  44. package/sub-skills/plugins/browser-extension.md +308 -308
  45. package/sub-skills/plugins/jetbrains-plugin.md +226 -226
  46. package/sub-skills/plugins/vscode-extension.md +204 -204
  47. package/sub-skills/security/security-tools.md +174 -174
  48. package/sub-skills/web/monorepo.md +274 -274
  49. package/sub-skills/web/pwa.md +220 -220
  50. package/sub-skills/web/serverless-edge.md +295 -295
  51. package/sub-skills/web/spa.md +266 -266
  52. package/sub-skills/web/ssr.md +228 -228
  53. package/sub-skills/web/wasm.md +243 -243
@@ -1,307 +1,307 @@
1
- # Payment Integration Build Sub-Skill
2
-
3
- Integrate payment systems into applications during build and packaging.
4
-
5
- **Current versions**: Stripe API 2024-12 / Alipay / WeChat Pay / Apple IAP / Google Play Billing (2025-2026)
6
-
7
- ## When to Use
8
-
9
- - SaaS applications with subscription billing
10
- - E-commerce applications
11
- - Mobile apps with in-app purchases
12
- - Marketplace / platform payments
13
- - Donations / tipping
14
-
15
- ## Payment Platform Comparison
16
-
17
- | Platform | Coverage | Fee | Best For |
18
- |----------|----------|-----|---------|
19
- | Stripe | Global (46+ countries) | 2.9% + $0.30/txn | Global SaaS, web apps |
20
- | Alipay | China | 0.6% | China market |
21
- | WeChat Pay | China | 0.6% | China market, mini-programs |
22
- | PayPal | Global | 2.9% + $0.30/txn | Broad consumer reach |
23
- | Apple IAP | iOS/macOS | 15–30% | iOS in-app purchases (required) |
24
- | Google Play Billing | Android | 15–30% | Android in-app purchases (required) |
25
- | Paddle | Global | 5% + fee | SaaS (handles tax/compliance) |
26
- | LemonSqueezy | Global | 5% + fee | Digital products, indie SaaS |
27
-
28
- ---
29
-
30
- ## Stripe Integration
31
-
32
- ### Web (Node.js Backend)
33
-
34
- ```bash
35
- npm install stripe
36
- ```
37
-
38
- ```javascript
39
- // server/stripe.js
40
- const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
41
-
42
- // Create checkout session
43
- app.post('/create-checkout', async (req, res) => {
44
- const session = await stripe.checkout.sessions.create({
45
- payment_method_types: ['card'],
46
- line_items: [{
47
- price_data: {
48
- currency: 'usd',
49
- product_data: { name: 'My Product' },
50
- unit_amount: 2000, // $20.00
51
- },
52
- quantity: 1,
53
- }],
54
- mode: 'payment',
55
- success_url: `${process.env.APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
56
- cancel_url: `${process.env.APP_URL}/cancel`,
57
- });
58
- res.json({ url: session.url });
59
- });
60
-
61
- // Webhook handler (required for production)
62
- app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
63
- const sig = req.headers['stripe-signature'];
64
- const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
65
-
66
- switch (event.type) {
67
- case 'checkout.session.completed':
68
- // Fulfill order
69
- break;
70
- case 'invoice.paid':
71
- // Update subscription status
72
- break;
73
- }
74
- res.json({ received: true });
75
- });
76
- ```
77
-
78
- ### React Frontend
79
-
80
- ```bash
81
- npm install @stripe/stripe-js @stripe/react-stripe-js
82
- ```
83
-
84
- ```javascript
85
- import { loadStripe } from '@stripe/stripe-js';
86
- import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
87
-
88
- const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY);
89
- ```
90
-
91
- ### Subscription Billing
92
-
93
- ```javascript
94
- // Create subscription
95
- const subscription = await stripe.subscriptions.create({
96
- customer: customerId,
97
- items: [{ price: 'price_monthly_xxx' }],
98
- payment_behavior: 'default_incomplete',
99
- expand: ['latest_invoice.payment_intent'],
100
- });
101
- ```
102
-
103
- ---
104
-
105
- ## Alipay & WeChat Pay
106
-
107
- ### Stripe + Alipay/WeChat (Recommended for international)
108
-
109
- ```javascript
110
- // Stripe supports Alipay and WeChat Pay as payment methods
111
- const session = await stripe.checkout.sessions.create({
112
- payment_method_types: ['card', 'alipay', 'wechat_pay'],
113
- // ...
114
- });
115
- ```
116
-
117
- ### Native Alipay SDK
118
-
119
- ```bash
120
- pip install alipay-sdk-python
121
- ```
122
-
123
- ```python
124
- from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
125
- from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
126
-
127
- config = AlipayClientConfig()
128
- config.app_id = "your_app_id"
129
- config.app_private_key = "your_private_key"
130
- config.alipay_public_key = "alipay_public_key"
131
-
132
- client = DefaultAlipayClient(config)
133
- ```
134
-
135
- ### Native WeChat Pay SDK
136
-
137
- ```xml
138
- <!-- Java/Maven -->
139
- <dependency>
140
- <groupId>com.github.wxpay</groupId>
141
- <artifactId>wxpay-sdk</artifactId>
142
- <version>3.4.0</version>
143
- </dependency>
144
- ```
145
-
146
- ---
147
-
148
- ## Apple In-App Purchase (IAP)
149
-
150
- ### When Required
151
-
152
- - Digital content consumed in the app (subscriptions, premium features, virtual goods)
153
- - **Physical goods**: Use Stripe/PayPal instead
154
- - **External links**: Apple allows external payment links in some regions (EU, US)
155
-
156
- ### Swift Implementation
157
-
158
- ```swift
159
- import StoreKit
160
-
161
- class StoreManager: ObservableObject {
162
- @Published var products: [Product] = []
163
-
164
- func loadProducts() async {
165
- do {
166
- products = try await Product.products(for: ["com.app.premium_monthly", "com.app.premium_yearly"])
167
- } catch {
168
- print("Failed to load products: \(error)")
169
- }
170
- }
171
-
172
- func purchase(_ product: Product) async throws -> Transaction? {
173
- let result = try await product.purchase()
174
- switch result {
175
- case .success(let verification):
176
- let transaction = try checkVerified(verification)
177
- await transaction.finish()
178
- return transaction
179
- case .userCancelled:
180
- return nil
181
- case .pending:
182
- return nil
183
- @unknown default:
184
- return nil
185
- }
186
- }
187
- }
188
- ```
189
-
190
- ### App Store Configuration
191
-
192
- ```
193
- 1. App Store Connect → In-App Purchases → Create
194
- 2. Set product ID, price, localization
195
- 3. Submit for review (can take 24-48 hours)
196
- 4. Implement receipt validation on server (recommended)
197
- ```
198
-
199
- ---
200
-
201
- ## Google Play Billing
202
-
203
- ### Kotlin Implementation
204
-
205
- ```kotlin
206
- // build.gradle.kts
207
- dependencies {
208
- implementation("com.android.billingclient:billing-ktx:7.0.0")
209
- }
210
-
211
- // BillingManager.kt
212
- class BillingManager(context: Context) {
213
- private val billingClient = BillingClient.newBuilder(context)
214
- .setListener { billingResult, purchases ->
215
- if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
216
- for (purchase in purchases) handlePurchase(purchase)
217
- }
218
- }
219
- .enablePendingPurchases()
220
- .build()
221
-
222
- fun startConnection() {
223
- billingClient.startConnection(object : BillingClientStateListener {
224
- override fun onBillingSetupFinished(result: BillingResult) {
225
- if (result.responseCode == BillingClient.BillingResponseCode.OK) {
226
- queryProducts()
227
- }
228
- }
229
- override fun onBillingServiceDisconnected() { /* retry */ }
230
- })
231
- }
232
-
233
- private fun queryProducts() {
234
- val productList = listOf(
235
- QueryProductDetailsParams.Product.newBuilder()
236
- .setProductId("premium_monthly")
237
- .setProductType(BillingClient.ProductType.SUBS)
238
- .build()
239
- )
240
- val params = QueryProductDetailsParams.newBuilder().setProductList(productList).build()
241
- billingClient.queryProductDetailsAsync(params) { result, productDetailsList ->
242
- // Display products to user
243
- }
244
- }
245
- }
246
- ```
247
-
248
- ### Google Play Console Configuration
249
-
250
- ```
251
- 1. Google Play Console → Monetize → Products → Subscriptions
252
- 2. Create subscription product with base plan
253
- 3. Set pricing, grace period, offers
254
- 4. Upload app with billing permission
255
- 5. Test with license testers
256
- ```
257
-
258
- ---
259
-
260
- ## Server-Side Receipt Validation (Critical for Security)
261
-
262
- ```javascript
263
- // Apple receipt validation
264
- const appleReceiptVerify = require('node-apple-receipt-verify');
265
- appleReceiptVerify.config({ secret: process.env.APPLE_SHARED_SECRET });
266
-
267
- const products = await appleReceiptVerify.validate({
268
- receipt: receiptData,
269
- verbose: true,
270
- });
271
-
272
- // Google Play receipt validation
273
- const { google } = require('googleapis');
274
- const androidpublisher = google.androidpublisher('v3');
275
- const purchase = await androidpublisher.purchases.subscriptions.get({
276
- packageName: 'com.example.app',
277
- subscriptionId: 'premium_monthly',
278
- token: purchaseToken,
279
- });
280
- ```
281
-
282
- ---
283
-
284
- ## Payment Security Checklist
285
-
286
- | Requirement | Implementation |
287
- |-------------|---------------|
288
- | **Never trust client-side** | Always validate payments server-side |
289
- | **Webhook signature verification** | Verify Stripe/Alipay webhook signatures |
290
- | **HTTPS only** | All payment pages must use HTTPS |
291
- | **PCI compliance** | Use Stripe Elements (no raw card data on your server) |
292
- | **Idempotency** | Use idempotency keys to prevent double charges |
293
- | **Receipt validation** | Validate IAP receipts server-side (Apple/Google) |
294
- | **Fraud detection** | Implement rate limiting; flag suspicious patterns |
295
- | **Secure key storage** | Use environment variables / secret managers; never commit keys |
296
-
297
- ## Common Pitfalls
298
-
299
- | Issue | Fix |
300
- |-------|-----|
301
- | Apple IAP rejected | Ensure IAP is for digital content; physical goods use other processors |
302
- | Stripe webhook not receiving | Check webhook URL; verify signature; use Stripe CLI for testing |
303
- | Double charges | Implement idempotency keys; check payment status before fulfilling |
304
- | Currency mismatch | Use `currency` consistently; Stripe amounts are in cents |
305
- | Alipay/WeChat cross-border | Use Stripe's built-in support; or apply for merchant accounts directly |
306
- | Google Play billing crash | Handle `BillingClientStateListener` disconnection; retry logic |
307
- | Tax compliance | Use Stripe Tax or Paddle for automatic tax calculation |
1
+ # Payment Integration Build Sub-Skill
2
+
3
+ Integrate payment systems into applications during build and packaging.
4
+
5
+ **Current versions**: Stripe API 2024-12 / Alipay / WeChat Pay / Apple IAP / Google Play Billing (2025-2026)
6
+
7
+ ## When to Use
8
+
9
+ - SaaS applications with subscription billing
10
+ - E-commerce applications
11
+ - Mobile apps with in-app purchases
12
+ - Marketplace / platform payments
13
+ - Donations / tipping
14
+
15
+ ## Payment Platform Comparison
16
+
17
+ | Platform | Coverage | Fee | Best For |
18
+ |----------|----------|-----|---------|
19
+ | Stripe | Global (46+ countries) | 2.9% + $0.30/txn | Global SaaS, web apps |
20
+ | Alipay | China | 0.6% | China market |
21
+ | WeChat Pay | China | 0.6% | China market, mini-programs |
22
+ | PayPal | Global | 2.9% + $0.30/txn | Broad consumer reach |
23
+ | Apple IAP | iOS/macOS | 15–30% | iOS in-app purchases (required) |
24
+ | Google Play Billing | Android | 15–30% | Android in-app purchases (required) |
25
+ | Paddle | Global | 5% + fee | SaaS (handles tax/compliance) |
26
+ | LemonSqueezy | Global | 5% + fee | Digital products, indie SaaS |
27
+
28
+ ---
29
+
30
+ ## Stripe Integration
31
+
32
+ ### Web (Node.js Backend)
33
+
34
+ ```bash
35
+ npm install stripe
36
+ ```
37
+
38
+ ```javascript
39
+ // server/stripe.js
40
+ const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
41
+
42
+ // Create checkout session
43
+ app.post('/create-checkout', async (req, res) => {
44
+ const session = await stripe.checkout.sessions.create({
45
+ payment_method_types: ['card'],
46
+ line_items: [{
47
+ price_data: {
48
+ currency: 'usd',
49
+ product_data: { name: 'My Product' },
50
+ unit_amount: 2000, // $20.00
51
+ },
52
+ quantity: 1,
53
+ }],
54
+ mode: 'payment',
55
+ success_url: `${process.env.APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
56
+ cancel_url: `${process.env.APP_URL}/cancel`,
57
+ });
58
+ res.json({ url: session.url });
59
+ });
60
+
61
+ // Webhook handler (required for production)
62
+ app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
63
+ const sig = req.headers['stripe-signature'];
64
+ const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
65
+
66
+ switch (event.type) {
67
+ case 'checkout.session.completed':
68
+ // Fulfill order
69
+ break;
70
+ case 'invoice.paid':
71
+ // Update subscription status
72
+ break;
73
+ }
74
+ res.json({ received: true });
75
+ });
76
+ ```
77
+
78
+ ### React Frontend
79
+
80
+ ```bash
81
+ npm install @stripe/stripe-js @stripe/react-stripe-js
82
+ ```
83
+
84
+ ```javascript
85
+ import { loadStripe } from '@stripe/stripe-js';
86
+ import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
87
+
88
+ const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY);
89
+ ```
90
+
91
+ ### Subscription Billing
92
+
93
+ ```javascript
94
+ // Create subscription
95
+ const subscription = await stripe.subscriptions.create({
96
+ customer: customerId,
97
+ items: [{ price: 'price_monthly_xxx' }],
98
+ payment_behavior: 'default_incomplete',
99
+ expand: ['latest_invoice.payment_intent'],
100
+ });
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Alipay & WeChat Pay
106
+
107
+ ### Stripe + Alipay/WeChat (Recommended for international)
108
+
109
+ ```javascript
110
+ // Stripe supports Alipay and WeChat Pay as payment methods
111
+ const session = await stripe.checkout.sessions.create({
112
+ payment_method_types: ['card', 'alipay', 'wechat_pay'],
113
+ // ...
114
+ });
115
+ ```
116
+
117
+ ### Native Alipay SDK
118
+
119
+ ```bash
120
+ pip install alipay-sdk-python
121
+ ```
122
+
123
+ ```python
124
+ from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
125
+ from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
126
+
127
+ config = AlipayClientConfig()
128
+ config.app_id = "your_app_id"
129
+ config.app_private_key = "your_private_key"
130
+ config.alipay_public_key = "alipay_public_key"
131
+
132
+ client = DefaultAlipayClient(config)
133
+ ```
134
+
135
+ ### Native WeChat Pay SDK
136
+
137
+ ```xml
138
+ <!-- Java/Maven -->
139
+ <dependency>
140
+ <groupId>com.github.wxpay</groupId>
141
+ <artifactId>wxpay-sdk</artifactId>
142
+ <version>3.4.0</version>
143
+ </dependency>
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Apple In-App Purchase (IAP)
149
+
150
+ ### When Required
151
+
152
+ - Digital content consumed in the app (subscriptions, premium features, virtual goods)
153
+ - **Physical goods**: Use Stripe/PayPal instead
154
+ - **External links**: Apple allows external payment links in some regions (EU, US)
155
+
156
+ ### Swift Implementation
157
+
158
+ ```swift
159
+ import StoreKit
160
+
161
+ class StoreManager: ObservableObject {
162
+ @Published var products: [Product] = []
163
+
164
+ func loadProducts() async {
165
+ do {
166
+ products = try await Product.products(for: ["com.app.premium_monthly", "com.app.premium_yearly"])
167
+ } catch {
168
+ print("Failed to load products: \(error)")
169
+ }
170
+ }
171
+
172
+ func purchase(_ product: Product) async throws -> Transaction? {
173
+ let result = try await product.purchase()
174
+ switch result {
175
+ case .success(let verification):
176
+ let transaction = try checkVerified(verification)
177
+ await transaction.finish()
178
+ return transaction
179
+ case .userCancelled:
180
+ return nil
181
+ case .pending:
182
+ return nil
183
+ @unknown default:
184
+ return nil
185
+ }
186
+ }
187
+ }
188
+ ```
189
+
190
+ ### App Store Configuration
191
+
192
+ ```
193
+ 1. App Store Connect → In-App Purchases → Create
194
+ 2. Set product ID, price, localization
195
+ 3. Submit for review (can take 24-48 hours)
196
+ 4. Implement receipt validation on server (recommended)
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Google Play Billing
202
+
203
+ ### Kotlin Implementation
204
+
205
+ ```kotlin
206
+ // build.gradle.kts
207
+ dependencies {
208
+ implementation("com.android.billingclient:billing-ktx:7.0.0")
209
+ }
210
+
211
+ // BillingManager.kt
212
+ class BillingManager(context: Context) {
213
+ private val billingClient = BillingClient.newBuilder(context)
214
+ .setListener { billingResult, purchases ->
215
+ if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
216
+ for (purchase in purchases) handlePurchase(purchase)
217
+ }
218
+ }
219
+ .enablePendingPurchases()
220
+ .build()
221
+
222
+ fun startConnection() {
223
+ billingClient.startConnection(object : BillingClientStateListener {
224
+ override fun onBillingSetupFinished(result: BillingResult) {
225
+ if (result.responseCode == BillingClient.BillingResponseCode.OK) {
226
+ queryProducts()
227
+ }
228
+ }
229
+ override fun onBillingServiceDisconnected() { /* retry */ }
230
+ })
231
+ }
232
+
233
+ private fun queryProducts() {
234
+ val productList = listOf(
235
+ QueryProductDetailsParams.Product.newBuilder()
236
+ .setProductId("premium_monthly")
237
+ .setProductType(BillingClient.ProductType.SUBS)
238
+ .build()
239
+ )
240
+ val params = QueryProductDetailsParams.newBuilder().setProductList(productList).build()
241
+ billingClient.queryProductDetailsAsync(params) { result, productDetailsList ->
242
+ // Display products to user
243
+ }
244
+ }
245
+ }
246
+ ```
247
+
248
+ ### Google Play Console Configuration
249
+
250
+ ```
251
+ 1. Google Play Console → Monetize → Products → Subscriptions
252
+ 2. Create subscription product with base plan
253
+ 3. Set pricing, grace period, offers
254
+ 4. Upload app with billing permission
255
+ 5. Test with license testers
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Server-Side Receipt Validation (Critical for Security)
261
+
262
+ ```javascript
263
+ // Apple receipt validation
264
+ const appleReceiptVerify = require('node-apple-receipt-verify');
265
+ appleReceiptVerify.config({ secret: process.env.APPLE_SHARED_SECRET });
266
+
267
+ const products = await appleReceiptVerify.validate({
268
+ receipt: receiptData,
269
+ verbose: true,
270
+ });
271
+
272
+ // Google Play receipt validation
273
+ const { google } = require('googleapis');
274
+ const androidpublisher = google.androidpublisher('v3');
275
+ const purchase = await androidpublisher.purchases.subscriptions.get({
276
+ packageName: 'com.example.app',
277
+ subscriptionId: 'premium_monthly',
278
+ token: purchaseToken,
279
+ });
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Payment Security Checklist
285
+
286
+ | Requirement | Implementation |
287
+ |-------------|---------------|
288
+ | **Never trust client-side** | Always validate payments server-side |
289
+ | **Webhook signature verification** | Verify Stripe/Alipay webhook signatures |
290
+ | **HTTPS only** | All payment pages must use HTTPS |
291
+ | **PCI compliance** | Use Stripe Elements (no raw card data on your server) |
292
+ | **Idempotency** | Use idempotency keys to prevent double charges |
293
+ | **Receipt validation** | Validate IAP receipts server-side (Apple/Google) |
294
+ | **Fraud detection** | Implement rate limiting; flag suspicious patterns |
295
+ | **Secure key storage** | Use environment variables / secret managers; never commit keys |
296
+
297
+ ## Common Pitfalls
298
+
299
+ | Issue | Fix |
300
+ |-------|-----|
301
+ | Apple IAP rejected | Ensure IAP is for digital content; physical goods use other processors |
302
+ | Stripe webhook not receiving | Check webhook URL; verify signature; use Stripe CLI for testing |
303
+ | Double charges | Implement idempotency keys; check payment status before fulfilling |
304
+ | Currency mismatch | Use `currency` consistently; Stripe amounts are in cents |
305
+ | Alipay/WeChat cross-border | Use Stripe's built-in support; or apply for merchant accounts directly |
306
+ | Google Play billing crash | Handle `BillingClientStateListener` disconnection; retry logic |
307
+ | Tax compliance | Use Stripe Tax or Paddle for automatic tax calculation |