@sylix/coworker 2.0.10 → 2.0.12

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 (178) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +23 -5
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/commands/slash/todo.js +1 -1
  5. package/dist/commands/slash/todo.js.map +1 -1
  6. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  7. package/dist/core/CoWorkerAgent.js +6 -3
  8. package/dist/core/CoWorkerAgent.js.map +1 -1
  9. package/dist/permissions/PermissionInterceptor.js +1 -1
  10. package/dist/permissions/PermissionInterceptor.js.map +1 -1
  11. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  12. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  13. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  14. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  15. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  16. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  17. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  18. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  19. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  20. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  21. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  22. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  23. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  24. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  25. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  26. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  27. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  28. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  29. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  30. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  31. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  32. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  33. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  34. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  35. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  36. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  37. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  38. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  39. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  40. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  41. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  42. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  43. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  44. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  45. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  46. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  47. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  48. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  49. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  50. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  51. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  52. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  53. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  54. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  55. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  56. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  57. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  58. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  59. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  60. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  61. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  62. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  63. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  64. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  65. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  66. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  67. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  68. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  69. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  70. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  71. package/dist/skills/defaults/database/postgresql.md +202 -0
  72. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  73. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  74. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  75. package/dist/skills/defaults/devops/cicd.md +314 -0
  76. package/dist/skills/defaults/devops/cloud.md +263 -0
  77. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  78. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  79. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  80. package/dist/skills/defaults/devops/docker.md +281 -0
  81. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  82. package/dist/skills/defaults/devops/github-actions.md +311 -0
  83. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  84. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  85. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  86. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  87. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  88. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  89. package/dist/skills/defaults/devops/observability.md +243 -0
  90. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  91. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  92. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  93. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  94. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  95. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  96. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  97. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  98. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  99. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  100. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  101. package/dist/skills/defaults/frontend/javascript.md +311 -0
  102. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  103. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  104. package/dist/skills/defaults/frontend/react.md +345 -0
  105. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  106. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  107. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  108. package/dist/skills/defaults/frontend/typescript.md +334 -0
  109. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  110. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  111. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  112. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  113. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  114. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  115. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  116. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  117. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  118. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  119. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  120. package/dist/skills/defaults/kubernetes/security.md +337 -0
  121. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  122. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  123. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  124. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  125. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  126. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  127. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  128. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  129. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  130. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  131. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  132. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  133. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  134. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  135. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  136. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  137. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  138. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  139. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  140. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  141. package/dist/skills/defaults/security/auditor.md +168 -0
  142. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  143. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  144. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  145. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  146. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  147. package/dist/skills/defaults/security/security.md +313 -0
  148. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  149. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  150. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  151. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  152. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  153. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  154. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  155. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  156. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  157. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  158. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  159. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  160. package/dist/skills/defaults/testing/testing.md +332 -0
  161. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  162. package/dist/skills/defaults/workflows/track-management.md +592 -0
  163. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  164. package/dist/skills/index.d.ts +11 -0
  165. package/dist/skills/index.d.ts.map +1 -0
  166. package/dist/skills/index.js +129 -0
  167. package/dist/skills/index.js.map +1 -0
  168. package/dist/utils/character.js +6 -9
  169. package/dist/utils/character.js.map +1 -1
  170. package/dist/utils/contextManager.js +3 -7
  171. package/dist/utils/contextManager.js.map +1 -1
  172. package/dist/utils/inputbar.d.ts.map +1 -1
  173. package/dist/utils/inputbar.js +8 -1
  174. package/dist/utils/inputbar.js.map +1 -1
  175. package/dist/utils/output.d.ts.map +1 -1
  176. package/dist/utils/output.js +3 -35
  177. package/dist/utils/output.js.map +1 -1
  178. package/package.json +1 -1
@@ -0,0 +1,478 @@
1
+ ---
2
+ name: paypal-integration
3
+ description: Integrate PayPal payment processing with support for express checkout, subscriptions, and refund management. Use when implementing PayPal payments, processing online transactions, or building e-commerce checkout flows.
4
+ ---
5
+
6
+ # PayPal Integration
7
+
8
+ Master PayPal payment integration including Express Checkout, IPN handling, recurring billing, and refund workflows.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Integrating PayPal as a payment option
13
+ - Implementing express checkout flows
14
+ - Setting up recurring billing with PayPal
15
+ - Processing refunds and payment disputes
16
+ - Handling PayPal webhooks (IPN)
17
+ - Supporting international payments
18
+ - Implementing PayPal subscriptions
19
+
20
+ ## Core Concepts
21
+
22
+ ### 1. Payment Products
23
+
24
+ **PayPal Checkout**
25
+
26
+ - One-time payments
27
+ - Express checkout experience
28
+ - Guest and PayPal account payments
29
+
30
+ **PayPal Subscriptions**
31
+
32
+ - Recurring billing
33
+ - Subscription plans
34
+ - Automatic renewals
35
+
36
+ **PayPal Payouts**
37
+
38
+ - Send money to multiple recipients
39
+ - Marketplace and platform payments
40
+
41
+ ### 2. Integration Methods
42
+
43
+ **Client-Side (JavaScript SDK)**
44
+
45
+ - Smart Payment Buttons
46
+ - Hosted payment flow
47
+ - Minimal backend code
48
+
49
+ **Server-Side (REST API)**
50
+
51
+ - Full control over payment flow
52
+ - Custom checkout UI
53
+ - Advanced features
54
+
55
+ ### 3. IPN (Instant Payment Notification)
56
+
57
+ - Webhook-like payment notifications
58
+ - Asynchronous payment updates
59
+ - Verification required
60
+
61
+ ## Quick Start
62
+
63
+ ```javascript
64
+ // Frontend - PayPal Smart Buttons
65
+ <div id="paypal-button-container"></div>
66
+
67
+ <script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&currency=USD"></script>
68
+ <script>
69
+ paypal.Buttons({
70
+ createOrder: function(data, actions) {
71
+ return actions.order.create({
72
+ purchase_units: [{
73
+ amount: {
74
+ value: '25.00'
75
+ }
76
+ }]
77
+ });
78
+ },
79
+ onApprove: function(data, actions) {
80
+ return actions.order.capture().then(function(details) {
81
+ // Payment successful
82
+ console.log('Transaction completed by ' + details.payer.name.given_name);
83
+
84
+ // Send to backend for verification
85
+ fetch('/api/paypal/capture', {
86
+ method: 'POST',
87
+ headers: {'Content-Type': 'application/json'},
88
+ body: JSON.stringify({orderID: data.orderID})
89
+ });
90
+ });
91
+ }
92
+ }).render('#paypal-button-container');
93
+ </script>
94
+ ```
95
+
96
+ ```python
97
+ # Backend - Verify and capture order
98
+ from paypalrestsdk import Payment
99
+ import paypalrestsdk
100
+
101
+ paypalrestsdk.configure({
102
+ "mode": "sandbox", # or "live"
103
+ "client_id": "YOUR_CLIENT_ID",
104
+ "client_secret": "YOUR_CLIENT_SECRET"
105
+ })
106
+
107
+ def capture_paypal_order(order_id):
108
+ """Capture a PayPal order."""
109
+ payment = Payment.find(order_id)
110
+
111
+ if payment.execute({"payer_id": payment.payer.payer_info.payer_id}):
112
+ # Payment successful
113
+ return {
114
+ 'status': 'success',
115
+ 'transaction_id': payment.id,
116
+ 'amount': payment.transactions[0].amount.total
117
+ }
118
+ else:
119
+ # Payment failed
120
+ return {
121
+ 'status': 'failed',
122
+ 'error': payment.error
123
+ }
124
+ ```
125
+
126
+ ## Express Checkout Implementation
127
+
128
+ ### Server-Side Order Creation
129
+
130
+ ```python
131
+ import requests
132
+ import json
133
+
134
+ class PayPalClient:
135
+ def __init__(self, client_id, client_secret, mode='sandbox'):
136
+ self.client_id = client_id
137
+ self.client_secret = client_secret
138
+ self.base_url = 'https://api-m.sandbox.paypal.com' if mode == 'sandbox' else 'https://api-m.paypal.com'
139
+ self.access_token = self.get_access_token()
140
+
141
+ def get_access_token(self):
142
+ """Get OAuth access token."""
143
+ url = f"{self.base_url}/v1/oauth2/token"
144
+ headers = {"Accept": "application/json", "Accept-Language": "en_US"}
145
+
146
+ response = requests.post(
147
+ url,
148
+ headers=headers,
149
+ data={"grant_type": "client_credentials"},
150
+ auth=(self.client_id, self.client_secret)
151
+ )
152
+
153
+ return response.json()['access_token']
154
+
155
+ def create_order(self, amount, currency='USD'):
156
+ """Create a PayPal order."""
157
+ url = f"{self.base_url}/v2/checkout/orders"
158
+ headers = {
159
+ "Content-Type": "application/json",
160
+ "Authorization": f"Bearer {self.access_token}"
161
+ }
162
+
163
+ payload = {
164
+ "intent": "CAPTURE",
165
+ "purchase_units": [{
166
+ "amount": {
167
+ "currency_code": currency,
168
+ "value": str(amount)
169
+ }
170
+ }]
171
+ }
172
+
173
+ response = requests.post(url, headers=headers, json=payload)
174
+ return response.json()
175
+
176
+ def capture_order(self, order_id):
177
+ """Capture payment for an order."""
178
+ url = f"{self.base_url}/v2/checkout/orders/{order_id}/capture"
179
+ headers = {
180
+ "Content-Type": "application/json",
181
+ "Authorization": f"Bearer {self.access_token}"
182
+ }
183
+
184
+ response = requests.post(url, headers=headers)
185
+ return response.json()
186
+
187
+ def get_order_details(self, order_id):
188
+ """Get order details."""
189
+ url = f"{self.base_url}/v2/checkout/orders/{order_id}"
190
+ headers = {
191
+ "Authorization": f"Bearer {self.access_token}"
192
+ }
193
+
194
+ response = requests.get(url, headers=headers)
195
+ return response.json()
196
+ ```
197
+
198
+ ## IPN (Instant Payment Notification) Handling
199
+
200
+ ### IPN Verification and Processing
201
+
202
+ ```python
203
+ from flask import Flask, request
204
+ import requests
205
+ from urllib.parse import parse_qs
206
+
207
+ app = Flask(__name__)
208
+
209
+ @app.route('/ipn', methods=['POST'])
210
+ def handle_ipn():
211
+ """Handle PayPal IPN notifications."""
212
+ # Get IPN message
213
+ ipn_data = request.form.to_dict()
214
+
215
+ # Verify IPN with PayPal
216
+ if not verify_ipn(ipn_data):
217
+ return 'IPN verification failed', 400
218
+
219
+ # Process IPN based on transaction type
220
+ payment_status = ipn_data.get('payment_status')
221
+ txn_type = ipn_data.get('txn_type')
222
+
223
+ if payment_status == 'Completed':
224
+ handle_payment_completed(ipn_data)
225
+ elif payment_status == 'Refunded':
226
+ handle_refund(ipn_data)
227
+ elif payment_status == 'Reversed':
228
+ handle_chargeback(ipn_data)
229
+
230
+ return 'IPN processed', 200
231
+
232
+ def verify_ipn(ipn_data):
233
+ """Verify IPN message authenticity."""
234
+ # Add 'cmd' parameter
235
+ verify_data = ipn_data.copy()
236
+ verify_data['cmd'] = '_notify-validate'
237
+
238
+ # Send back to PayPal for verification
239
+ paypal_url = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' # or production URL
240
+
241
+ response = requests.post(paypal_url, data=verify_data)
242
+
243
+ return response.text == 'VERIFIED'
244
+
245
+ def handle_payment_completed(ipn_data):
246
+ """Process completed payment."""
247
+ txn_id = ipn_data.get('txn_id')
248
+ payer_email = ipn_data.get('payer_email')
249
+ mc_gross = ipn_data.get('mc_gross')
250
+ item_name = ipn_data.get('item_name')
251
+
252
+ # Check if already processed (prevent duplicates)
253
+ if is_transaction_processed(txn_id):
254
+ return
255
+
256
+ # Update database
257
+ # Send confirmation email
258
+ # Fulfill order
259
+ print(f"Payment completed: {txn_id}, Amount: ${mc_gross}")
260
+
261
+ def handle_refund(ipn_data):
262
+ """Handle refund."""
263
+ parent_txn_id = ipn_data.get('parent_txn_id')
264
+ mc_gross = ipn_data.get('mc_gross')
265
+
266
+ # Process refund in your system
267
+ print(f"Refund processed: {parent_txn_id}, Amount: ${mc_gross}")
268
+
269
+ def handle_chargeback(ipn_data):
270
+ """Handle payment reversal/chargeback."""
271
+ txn_id = ipn_data.get('txn_id')
272
+ reason_code = ipn_data.get('reason_code')
273
+
274
+ # Handle chargeback
275
+ print(f"Chargeback: {txn_id}, Reason: {reason_code}")
276
+ ```
277
+
278
+ ## Subscription/Recurring Billing
279
+
280
+ ### Create Subscription Plan
281
+
282
+ ```python
283
+ def create_subscription_plan(name, amount, interval='MONTH'):
284
+ """Create a subscription plan."""
285
+ client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
286
+
287
+ url = f"{client.base_url}/v1/billing/plans"
288
+ headers = {
289
+ "Content-Type": "application/json",
290
+ "Authorization": f"Bearer {client.access_token}"
291
+ }
292
+
293
+ payload = {
294
+ "product_id": "PRODUCT_ID", # Create product first
295
+ "name": name,
296
+ "billing_cycles": [{
297
+ "frequency": {
298
+ "interval_unit": interval,
299
+ "interval_count": 1
300
+ },
301
+ "tenure_type": "REGULAR",
302
+ "sequence": 1,
303
+ "total_cycles": 0, # Infinite
304
+ "pricing_scheme": {
305
+ "fixed_price": {
306
+ "value": str(amount),
307
+ "currency_code": "USD"
308
+ }
309
+ }
310
+ }],
311
+ "payment_preferences": {
312
+ "auto_bill_outstanding": True,
313
+ "setup_fee": {
314
+ "value": "0",
315
+ "currency_code": "USD"
316
+ },
317
+ "setup_fee_failure_action": "CONTINUE",
318
+ "payment_failure_threshold": 3
319
+ }
320
+ }
321
+
322
+ response = requests.post(url, headers=headers, json=payload)
323
+ return response.json()
324
+
325
+ def create_subscription(plan_id, subscriber_email):
326
+ """Create a subscription for a customer."""
327
+ client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
328
+
329
+ url = f"{client.base_url}/v1/billing/subscriptions"
330
+ headers = {
331
+ "Content-Type": "application/json",
332
+ "Authorization": f"Bearer {client.access_token}"
333
+ }
334
+
335
+ payload = {
336
+ "plan_id": plan_id,
337
+ "subscriber": {
338
+ "email_address": subscriber_email
339
+ },
340
+ "application_context": {
341
+ "return_url": "https://yourdomain.com/subscription/success",
342
+ "cancel_url": "https://yourdomain.com/subscription/cancel"
343
+ }
344
+ }
345
+
346
+ response = requests.post(url, headers=headers, json=payload)
347
+ subscription = response.json()
348
+
349
+ # Get approval URL
350
+ for link in subscription.get('links', []):
351
+ if link['rel'] == 'approve':
352
+ return {
353
+ 'subscription_id': subscription['id'],
354
+ 'approval_url': link['href']
355
+ }
356
+ ```
357
+
358
+ ## Refund Workflows
359
+
360
+ ```python
361
+ def create_refund(capture_id, amount=None, note=None):
362
+ """Create a refund for a captured payment."""
363
+ client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
364
+
365
+ url = f"{client.base_url}/v2/payments/captures/{capture_id}/refund"
366
+ headers = {
367
+ "Content-Type": "application/json",
368
+ "Authorization": f"Bearer {client.access_token}"
369
+ }
370
+
371
+ payload = {}
372
+ if amount:
373
+ payload["amount"] = {
374
+ "value": str(amount),
375
+ "currency_code": "USD"
376
+ }
377
+
378
+ if note:
379
+ payload["note_to_payer"] = note
380
+
381
+ response = requests.post(url, headers=headers, json=payload)
382
+ return response.json()
383
+
384
+ def get_refund_details(refund_id):
385
+ """Get refund details."""
386
+ client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
387
+
388
+ url = f"{client.base_url}/v2/payments/refunds/{refund_id}"
389
+ headers = {
390
+ "Authorization": f"Bearer {client.access_token}"
391
+ }
392
+
393
+ response = requests.get(url, headers=headers)
394
+ return response.json()
395
+ ```
396
+
397
+ ## Error Handling
398
+
399
+ ```python
400
+ class PayPalError(Exception):
401
+ """Custom PayPal error."""
402
+ pass
403
+
404
+ def handle_paypal_api_call(api_function):
405
+ """Wrapper for PayPal API calls with error handling."""
406
+ try:
407
+ result = api_function()
408
+ return result
409
+ except requests.exceptions.RequestException as e:
410
+ # Network error
411
+ raise PayPalError(f"Network error: {str(e)}")
412
+ except Exception as e:
413
+ # Other errors
414
+ raise PayPalError(f"PayPal API error: {str(e)}")
415
+
416
+ # Usage
417
+ try:
418
+ order = handle_paypal_api_call(lambda: client.create_order(25.00))
419
+ except PayPalError as e:
420
+ # Handle error appropriately
421
+ log_error(e)
422
+ ```
423
+
424
+ ## Testing
425
+
426
+ ```python
427
+ # Use sandbox credentials
428
+ SANDBOX_CLIENT_ID = "..."
429
+ SANDBOX_SECRET = "..."
430
+
431
+ # Test accounts
432
+ # Create test buyer and seller accounts at developer.paypal.com
433
+
434
+ def test_payment_flow():
435
+ """Test complete payment flow."""
436
+ client = PayPalClient(SANDBOX_CLIENT_ID, SANDBOX_SECRET, mode='sandbox')
437
+
438
+ # Create order
439
+ order = client.create_order(10.00)
440
+ assert 'id' in order
441
+
442
+ # Get approval URL
443
+ approval_url = next((link['href'] for link in order['links'] if link['rel'] == 'approve'), None)
444
+ assert approval_url is not None
445
+
446
+ # After approval (manual step with test account)
447
+ # Capture order
448
+ # captured = client.capture_order(order['id'])
449
+ # assert captured['status'] == 'COMPLETED'
450
+ ```
451
+
452
+ ## Resources
453
+
454
+ - **references/express-checkout.md**: Express Checkout implementation guide
455
+ - **references/ipn-handling.md**: IPN verification and processing
456
+ - **references/refund-workflows.md**: Refund handling patterns
457
+ - **references/billing-agreements.md**: Recurring billing setup
458
+ - **assets/paypal-client.py**: Production PayPal client
459
+ - **assets/ipn-processor.py**: IPN webhook processor
460
+ - **assets/recurring-billing.py**: Subscription management
461
+
462
+ ## Best Practices
463
+
464
+ 1. **Always Verify IPN**: Never trust IPN without verification
465
+ 2. **Idempotent Processing**: Handle duplicate IPN notifications
466
+ 3. **Error Handling**: Implement robust error handling
467
+ 4. **Logging**: Log all transactions and errors
468
+ 5. **Test Thoroughly**: Use sandbox extensively
469
+ 6. **Webhook Backup**: Don't rely solely on client-side callbacks
470
+ 7. **Currency Handling**: Always specify currency explicitly
471
+
472
+ ## Common Pitfalls
473
+
474
+ - **Not Verifying IPN**: Accepting IPN without verification
475
+ - **Duplicate Processing**: Not checking for duplicate transactions
476
+ - **Wrong Environment**: Mixing sandbox and production URLs/credentials
477
+ - **Missing Webhooks**: Not handling all payment states
478
+ - **Hardcoded Values**: Not making configurable for different environments