{"id":"b7b9daed-8e49-45d8-ae9b-cd7f7af5fe78","shortId":"5CKgMf","kind":"skill","title":"paypal-integration","tagline":"Master PayPal payment integration including Express Checkout, IPN handling, recurring billing, and refund workflows.","description":"# PayPal Integration\n\nMaster PayPal payment integration including Express Checkout, IPN handling, recurring billing, and refund workflows.\n\n## Do not use this skill when\n\n- The task is unrelated to paypal integration\n- You need a different domain or tool outside this scope\n\n## Instructions\n\n- Clarify goals, constraints, and required inputs.\n- Apply relevant best practices and validate outcomes.\n- Provide actionable steps and verification.\n- If detailed examples are required, open `resources/implementation-playbook.md`.\n\n## Use this skill when\n\n- Integrating PayPal as a payment option\n- Implementing express checkout flows\n- Setting up recurring billing with PayPal\n- Processing refunds and payment disputes\n- Handling PayPal webhooks (IPN)\n- Supporting international payments\n- Implementing PayPal subscriptions\n\n## Core Concepts\n\n### 1. Payment Products\n**PayPal Checkout**\n- One-time payments\n- Express checkout experience\n- Guest and PayPal account payments\n\n**PayPal Subscriptions**\n- Recurring billing\n- Subscription plans\n- Automatic renewals\n\n**PayPal Payouts**\n- Send money to multiple recipients\n- Marketplace and platform payments\n\n### 2. Integration Methods\n**Client-Side (JavaScript SDK)**\n- Smart Payment Buttons\n- Hosted payment flow\n- Minimal backend code\n\n**Server-Side (REST API)**\n- Full control over payment flow\n- Custom checkout UI\n- Advanced features\n\n### 3. IPN (Instant Payment Notification)\n- Webhook-like payment notifications\n- Asynchronous payment updates\n- Verification required\n\n## Quick Start\n\n```javascript\n// Frontend - PayPal Smart Buttons\n<div id=\"paypal-button-container\"></div>\n\n<script src=\"https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&currency=USD\"></script>\n<script>\n  paypal.Buttons({\n    createOrder: function(data, actions) {\n      return actions.order.create({\n        purchase_units: [{\n          amount: {\n            value: '25.00'\n          }\n        }]\n      });\n    },\n    onApprove: function(data, actions) {\n      return actions.order.capture().then(function(details) {\n        // Payment successful\n        console.log('Transaction completed by ' + details.payer.name.given_name);\n\n        // Send to backend for verification\n        fetch('/api/paypal/capture', {\n          method: 'POST',\n          headers: {'Content-Type': 'application/json'},\n          body: JSON.stringify({orderID: data.orderID})\n        });\n      });\n    }\n  }).render('#paypal-button-container');\n</script>\n```\n\n```python\n# Backend - Verify and capture order\nfrom paypalrestsdk import Payment\nimport paypalrestsdk\n\npaypalrestsdk.configure({\n    \"mode\": \"sandbox\",  # or \"live\"\n    \"client_id\": \"YOUR_CLIENT_ID\",\n    \"client_secret\": \"YOUR_CLIENT_SECRET\"\n})\n\ndef capture_paypal_order(order_id):\n    \"\"\"Capture a PayPal order.\"\"\"\n    payment = Payment.find(order_id)\n\n    if payment.execute({\"payer_id\": payment.payer.payer_info.payer_id}):\n        # Payment successful\n        return {\n            'status': 'success',\n            'transaction_id': payment.id,\n            'amount': payment.transactions[0].amount.total\n        }\n    else:\n        # Payment failed\n        return {\n            'status': 'failed',\n            'error': payment.error\n        }\n```\n\n## Express Checkout Implementation\n\n### Server-Side Order Creation\n```python\nimport requests\nimport json\n\nclass PayPalClient:\n    def __init__(self, client_id, client_secret, mode='sandbox'):\n        self.client_id = client_id\n        self.client_secret = client_secret\n        self.base_url = 'https://api-m.sandbox.paypal.com' if mode == 'sandbox' else 'https://api-m.paypal.com'\n        self.access_token = self.get_access_token()\n\n    def get_access_token(self):\n        \"\"\"Get OAuth access token.\"\"\"\n        url = f\"{self.base_url}/v1/oauth2/token\"\n        headers = {\"Accept\": \"application/json\", \"Accept-Language\": \"en_US\"}\n\n        response = requests.post(\n            url,\n            headers=headers,\n            data={\"grant_type\": \"client_credentials\"},\n            auth=(self.client_id, self.client_secret)\n        )\n\n        return response.json()['access_token']\n\n    def create_order(self, amount, currency='USD'):\n        \"\"\"Create a PayPal order.\"\"\"\n        url = f\"{self.base_url}/v2/checkout/orders\"\n        headers = {\n            \"Content-Type\": \"application/json\",\n            \"Authorization\": f\"Bearer {self.access_token}\"\n        }\n\n        payload = {\n            \"intent\": \"CAPTURE\",\n            \"purchase_units\": [{\n                \"amount\": {\n                    \"currency_code\": currency,\n                    \"value\": str(amount)\n                }\n            }]\n        }\n\n        response = requests.post(url, headers=headers, json=payload)\n        return response.json()\n\n    def capture_order(self, order_id):\n        \"\"\"Capture payment for an order.\"\"\"\n        url = f\"{self.base_url}/v2/checkout/orders/{order_id}/capture\"\n        headers = {\n            \"Content-Type\": \"application/json\",\n            \"Authorization\": f\"Bearer {self.access_token}\"\n        }\n\n        response = requests.post(url, headers=headers)\n        return response.json()\n\n    def get_order_details(self, order_id):\n        \"\"\"Get order details.\"\"\"\n        url = f\"{self.base_url}/v2/checkout/orders/{order_id}\"\n        headers = {\n            \"Authorization\": f\"Bearer {self.access_token}\"\n        }\n\n        response = requests.get(url, headers=headers)\n        return response.json()\n```\n\n## IPN (Instant Payment Notification) Handling\n\n### IPN Verification and Processing\n```python\nfrom flask import Flask, request\nimport requests\nfrom urllib.parse import parse_qs\n\napp = Flask(__name__)\n\n@app.route('/ipn', methods=['POST'])\ndef handle_ipn():\n    \"\"\"Handle PayPal IPN notifications.\"\"\"\n    # Get IPN message\n    ipn_data = request.form.to_dict()\n\n    # Verify IPN with PayPal\n    if not verify_ipn(ipn_data):\n        return 'IPN verification failed', 400\n\n    # Process IPN based on transaction type\n    payment_status = ipn_data.get('payment_status')\n    txn_type = ipn_data.get('txn_type')\n\n    if payment_status == 'Completed':\n        handle_payment_completed(ipn_data)\n    elif payment_status == 'Refunded':\n        handle_refund(ipn_data)\n    elif payment_status == 'Reversed':\n        handle_chargeback(ipn_data)\n\n    return 'IPN processed', 200\n\ndef verify_ipn(ipn_data):\n    \"\"\"Verify IPN message authenticity.\"\"\"\n    # Add 'cmd' parameter\n    verify_data = ipn_data.copy()\n    verify_data['cmd'] = '_notify-validate'\n\n    # Send back to PayPal for verification\n    paypal_url = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr'  # or production URL\n\n    response = requests.post(paypal_url, data=verify_data)\n\n    return response.text == 'VERIFIED'\n\ndef handle_payment_completed(ipn_data):\n    \"\"\"Process completed payment.\"\"\"\n    txn_id = ipn_data.get('txn_id')\n    payer_email = ipn_data.get('payer_email')\n    mc_gross = ipn_data.get('mc_gross')\n    item_name = ipn_data.get('item_name')\n\n    # Check if already processed (prevent duplicates)\n    if is_transaction_processed(txn_id):\n        return\n\n    # Update database\n    # Send confirmation email\n    # Fulfill order\n    print(f\"Payment completed: {txn_id}, Amount: ${mc_gross}\")\n\ndef handle_refund(ipn_data):\n    \"\"\"Handle refund.\"\"\"\n    parent_txn_id = ipn_data.get('parent_txn_id')\n    mc_gross = ipn_data.get('mc_gross')\n\n    # Process refund in your system\n    print(f\"Refund processed: {parent_txn_id}, Amount: ${mc_gross}\")\n\ndef handle_chargeback(ipn_data):\n    \"\"\"Handle payment reversal/chargeback.\"\"\"\n    txn_id = ipn_data.get('txn_id')\n    reason_code = ipn_data.get('reason_code')\n\n    # Handle chargeback\n    print(f\"Chargeback: {txn_id}, Reason: {reason_code}\")\n```\n\n## Subscription/Recurring Billing\n\n### Create Subscription Plan\n```python\ndef create_subscription_plan(name, amount, interval='MONTH'):\n    \"\"\"Create a subscription plan.\"\"\"\n    client = PayPalClient(CLIENT_ID, CLIENT_SECRET)\n\n    url = f\"{client.base_url}/v1/billing/plans\"\n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"Authorization\": f\"Bearer {client.access_token}\"\n    }\n\n    payload = {\n        \"product_id\": \"PRODUCT_ID\",  # Create product first\n        \"name\": name,\n        \"billing_cycles\": [{\n            \"frequency\": {\n                \"interval_unit\": interval,\n                \"interval_count\": 1\n            },\n            \"tenure_type\": \"REGULAR\",\n            \"sequence\": 1,\n            \"total_cycles\": 0,  # Infinite\n            \"pricing_scheme\": {\n                \"fixed_price\": {\n                    \"value\": str(amount),\n                    \"currency_code\": \"USD\"\n                }\n            }\n        }],\n        \"payment_preferences\": {\n            \"auto_bill_outstanding\": True,\n            \"setup_fee\": {\n                \"value\": \"0\",\n                \"currency_code\": \"USD\"\n            },\n            \"setup_fee_failure_action\": \"CONTINUE\",\n            \"payment_failure_threshold\": 3\n        }\n    }\n\n    response = requests.post(url, headers=headers, json=payload)\n    return response.json()\n\ndef create_subscription(plan_id, subscriber_email):\n    \"\"\"Create a subscription for a customer.\"\"\"\n    client = PayPalClient(CLIENT_ID, CLIENT_SECRET)\n\n    url = f\"{client.base_url}/v1/billing/subscriptions\"\n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"Authorization\": f\"Bearer {client.access_token}\"\n    }\n\n    payload = {\n        \"plan_id\": plan_id,\n        \"subscriber\": {\n            \"email_address\": subscriber_email\n        },\n        \"application_context\": {\n            \"return_url\": \"https://yourdomain.com/subscription/success\",\n            \"cancel_url\": \"https://yourdomain.com/subscription/cancel\"\n        }\n    }\n\n    response = requests.post(url, headers=headers, json=payload)\n    subscription = response.json()\n\n    # Get approval URL\n    for link in subscription.get('links', []):\n        if link['rel'] == 'approve':\n            return {\n                'subscription_id': subscription['id'],\n                'approval_url': link['href']\n            }\n```\n\n## Refund Workflows\n\n```python\ndef create_refund(capture_id, amount=None, note=None):\n    \"\"\"Create a refund for a captured payment.\"\"\"\n    client = PayPalClient(CLIENT_ID, CLIENT_SECRET)\n\n    url = f\"{client.base_url}/v2/payments/captures/{capture_id}/refund\"\n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"Authorization\": f\"Bearer {client.access_token}\"\n    }\n\n    payload = {}\n    if amount:\n        payload[\"amount\"] = {\n            \"value\": str(amount),\n            \"currency_code\": \"USD\"\n        }\n\n    if note:\n        payload[\"note_to_payer\"] = note\n\n    response = requests.post(url, headers=headers, json=payload)\n    return response.json()\n\ndef get_refund_details(refund_id):\n    \"\"\"Get refund details.\"\"\"\n    client = PayPalClient(CLIENT_ID, CLIENT_SECRET)\n\n    url = f\"{client.base_url}/v2/payments/refunds/{refund_id}\"\n    headers = {\n        \"Authorization\": f\"Bearer {client.access_token}\"\n    }\n\n    response = requests.get(url, headers=headers)\n    return response.json()\n```\n\n## Error Handling\n\n```python\nclass PayPalError(Exception):\n    \"\"\"Custom PayPal error.\"\"\"\n    pass\n\ndef handle_paypal_api_call(api_function):\n    \"\"\"Wrapper for PayPal API calls with error handling.\"\"\"\n    try:\n        result = api_function()\n        return result\n    except requests.exceptions.RequestException as e:\n        # Network error\n        raise PayPalError(f\"Network error: {str(e)}\")\n    except Exception as e:\n        # Other errors\n        raise PayPalError(f\"PayPal API error: {str(e)}\")\n\n# Usage\ntry:\n    order = handle_paypal_api_call(lambda: client.create_order(25.00))\nexcept PayPalError as e:\n    # Handle error appropriately\n    log_error(e)\n```\n\n## Testing\n\n```python\n# Use sandbox credentials\nSANDBOX_CLIENT_ID = \"...\"\nSANDBOX_SECRET = \"...\"\n\n# Test accounts\n# Create test buyer and seller accounts at developer.paypal.com\n\ndef test_payment_flow():\n    \"\"\"Test complete payment flow.\"\"\"\n    client = PayPalClient(SANDBOX_CLIENT_ID, SANDBOX_SECRET, mode='sandbox')\n\n    # Create order\n    order = client.create_order(10.00)\n    assert 'id' in order\n\n    # Get approval URL\n    approval_url = next((link['href'] for link in order['links'] if link['rel'] == 'approve'), None)\n    assert approval_url is not None\n\n    # After approval (manual step with test account)\n    # Capture order\n    # captured = client.capture_order(order['id'])\n    # assert captured['status'] == 'COMPLETED'\n```\n\n## Resources\n\n- **references/express-checkout.md**: Express Checkout implementation guide\n- **references/ipn-handling.md**: IPN verification and processing\n- **references/refund-workflows.md**: Refund handling patterns\n- **references/billing-agreements.md**: Recurring billing setup\n- **assets/paypal-client.py**: Production PayPal client\n- **assets/ipn-processor.py**: IPN webhook processor\n- **assets/recurring-billing.py**: Subscription management\n\n## Best Practices\n\n1. **Always Verify IPN**: Never trust IPN without verification\n2. **Idempotent Processing**: Handle duplicate IPN notifications\n3. **Error Handling**: Implement robust error handling\n4. **Logging**: Log all transactions and errors\n5. **Test Thoroughly**: Use sandbox extensively\n6. **Webhook Backup**: Don't rely solely on client-side callbacks\n7. **Currency Handling**: Always specify currency explicitly\n\n## Common Pitfalls\n\n- **Not Verifying IPN**: Accepting IPN without verification\n- **Duplicate Processing**: Not checking for duplicate transactions\n- **Wrong Environment**: Mixing sandbox and production URLs/credentials\n- **Missing Webhooks**: Not handling all payment states\n- **Hardcoded Values**: Not making configurable for different environments\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["paypal","integration","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-paypal-integration","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/paypal-integration","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34616 github stars · SKILL.md body (13,990 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-23T00:51:22.532Z","embedding":null,"createdAt":"2026-04-18T21:42:12.974Z","updatedAt":"2026-04-23T00:51:22.532Z","lastSeenAt":"2026-04-23T00:51:22.532Z","tsv":"'/capture':428 '/cgi-bin/webscr''':610 '/ipn':502 '/refund':970 '/subscription/cancel':907 '/subscription/success':902 '/v1/billing/plans':772 '/v1/billing/subscriptions':875 '/v1/oauth2/token':335 '/v2/checkout/orders':378,425,460 '/v2/payments/captures':967 '/v2/payments/refunds':1027 '0':267,809,830 '1':120,801,806,1243 '10.00':1164 '2':156,1252 '200':578 '25.00':1111 '3':188,842,1259 '4':1266 '400':533 '5':1273 '6':1279 '7':1291 'accept':337,340,1303 'accept-languag':339 'access':320,324,329,361 'account':135,1133,1139,1199 'action':72,837 'add':588 'address':893 'advanc':186 'alreadi':655 'alway':1244,1294 'amount':265,367,394,400,679,713,755,817,946,983,985,988 'amount.total':268 'api':177,1056,1058,1063,1070,1097,1106 'api-m.paypal.com':316 'api-m.sandbox.paypal.com':311 'app':498 'app.route':501 'appli':64 'applic':896 'application/json':338,383,433,777,880,975 'appropri':1118 'approv':918,928,934,1170,1172,1185,1188,1194 'ask':1369 'assert':1165,1187,1207 'assets/ipn-processor.py':1234 'assets/paypal-client.py':1230 'assets/recurring-billing.py':1238 'asynchron':198 'auth':354 'authent':587 'author':384,434,464,778,881,976,1031 'auto':823 'automat':143 'back':601 'backend':171,211 'backup':1281 'base':536 'bearer':386,436,466,780,883,978,1033 'best':66,1241 'bill':14,30,100,140,745,793,824,1228 'boundari':1377 'button':166,209 'buyer':1136 'call':1057,1064,1107 'callback':1290 'cancel':903 'captur':214,238,243,391,411,416,944,955,968,1200,1202,1208 'chargeback':572,718,735,738 'check':653,1310 'checkout':10,26,95,124,130,184,278,1214 'clarif':1371 'clarifi':58 'class':290,1046 'clear':1344 'client':160,227,230,232,235,295,297,303,307,352,762,764,766,865,867,869,957,959,961,1017,1019,1021,1128,1150,1153,1233,1288 'client-sid':159,1287 'client.access':781,884,979,1034 'client.base':770,873,965,1025 'client.capture':1203 'client.create':1109,1162 'cmd':589,596 'code':172,396,730,733,743,819,832,990 'common':1298 'complet':553,556,627,631,676,1147,1210 'concept':119 'configur':1332 'confirm':669 'constraint':60 'content':381,431,775,878,973 'content-typ':380,430,774,877,972 'context':897 'continu':838 'control':179 'core':118 'count':800 'creat':364,370,746,751,758,788,853,859,942,950,1134,1159 'creation':284 'credenti':353,1126 'criteria':1380 'currenc':368,395,397,818,831,989,1292,1296 'custom':183,864,1049 'cycl':794,808 'data':349,516,528,558,566,574,583,592,595,618,620,629,686,720 'databas':667 'def':237,292,322,363,410,446,505,579,624,682,716,750,852,941,1008,1053,1142 'describ':1348 'detail':77,449,455,1011,1016 'developer.paypal.com':1141 'dict':518 'differ':50,1334 'disput':107 'domain':51 'duplic':658,1256,1307,1312 'e':1077,1086,1090,1100,1115,1121 'elif':559,567 'els':269,315 'email':639,642,670,858,892,895 'en':342 'environ':1315,1335,1360 'environment-specif':1359 'error':275,1043,1051,1066,1079,1084,1092,1098,1117,1120,1260,1264,1272 'exampl':78 'except':1048,1074,1087,1088,1112 'experi':131 'expert':1365 'explicit':1297 'express':9,25,94,129,277,1213 'extens':1278 'f':332,375,385,422,435,457,465,674,707,737,769,779,872,882,964,977,1024,1032,1082,1095 'fail':271,274,532 'failur':836,840 'featur':187 'fee':828,835 'first':790 'fix':813 'flask':487,489,499 'flow':96,169,182,1145,1149 'frequenc':795 'frontend':206 'fulfil':671 'full':178 'function':1059,1071 'get':323,327,447,453,512,917,1009,1014,1169 'goal':59 'grant':350 'gross':644,647,681,697,700,715 'guest':132 'guid':1216 'handl':12,28,108,480,506,508,554,563,571,625,683,687,717,721,734,1044,1054,1067,1104,1116,1224,1255,1261,1265,1293,1324 'hardcod':1328 'header':336,347,348,379,404,405,429,442,443,463,472,473,773,846,847,876,911,912,971,1002,1003,1030,1039,1040 'host':167 'href':937,1176 'id':228,231,242,250,254,256,263,296,302,304,356,415,427,452,462,634,637,664,678,691,695,712,725,728,740,765,785,787,856,868,888,890,931,933,945,960,969,1013,1020,1029,1129,1154,1166,1206 'idempot':1253 'implement':93,115,279,1215,1262 'import':218,220,286,288,488,491,495 'includ':8,24 'infinit':810 'init':293 'input':63,1374 'instant':190,477 'instruct':57 'integr':3,7,19,23,46,87,157 'intent':390 'intern':113 'interv':756,796,798,799 'ipn':11,27,111,189,476,481,507,510,513,515,520,526,527,530,535,557,565,573,576,581,582,585,628,685,719,1218,1235,1246,1249,1257,1302,1304 'ipn_data.copy':593 'ipn_data.get':542,547,635,640,645,650,692,698,726,731 'ipnpb.sandbox.paypal.com':609 'ipnpb.sandbox.paypal.com/cgi-bin/webscr''':608 'item':648,651 'javascript':162,205 'json':289,406,848,913,1004 'lambda':1108 'languag':341 'like':195 'limit':1336 'link':921,924,926,936,1175,1178,1181,1183 'live':226 'log':1119,1267,1268 'make':1331 'manag':1240 'manual':1195 'marketplac':152 'master':4,20 'match':1345 'mc':643,646,680,696,699,714 'messag':514,586 'method':158,503 'minim':170 'miss':1321,1382 'mix':1316 'mode':223,299,313,1157 'money':148 'month':757 'multipl':150 'name':500,649,652,754,791,792 'need':48 'network':1078,1083 'never':1247 'next':1174 'none':947,949,1186,1192 'note':948,993,995,998 'notif':192,197,479,511,1258 'notifi':598 'notify-valid':597 'oauth':328 'one':126 'one-tim':125 'open':81 'option':92 'order':215,240,241,246,249,283,365,373,412,414,420,426,448,451,454,461,672,1103,1110,1160,1161,1163,1168,1180,1201,1204,1205 'outcom':70 'output':1354 'outsid':54 'outstand':825 'paramet':590 'parent':689,693,710 'pars':496 'pass':1052 'pattern':1225 'payer':253,638,641,997 'payload':389,407,783,849,886,914,981,984,994,1005 'payment':6,22,91,106,114,121,128,136,155,165,168,181,191,196,199,219,247,257,270,417,478,540,543,551,555,560,568,626,632,675,722,821,839,956,1144,1148,1326 'payment.error':276 'payment.execute':252 'payment.find':248 'payment.id':264 'payment.payer.payer_info.payer':255 'payment.transactions':266 'payout':146 'paypal':2,5,18,21,45,88,102,109,116,123,134,137,145,207,239,245,372,509,522,603,606,616,1050,1055,1062,1096,1105,1232 'paypal-integr':1 'paypalcli':291,763,866,958,1018,1151 'paypalerror':1047,1081,1094,1113 'paypalrestsdk':217,221 'paypalrestsdk.configure':222 'permiss':1375 'pitfal':1299 'plan':142,748,753,761,855,887,889 'platform':154 'post':504 'practic':67,1242 'prefer':822 'prevent':657 'price':811,814 'print':673,706,736 'process':103,484,534,577,630,656,662,701,709,1221,1254,1308 'processor':1237 'product':122,612,784,786,789,1231,1319 'provid':71 'purchas':392 'python':210,285,485,749,940,1045,1123 'qs':497 'quick':203 'rais':1080,1093 'reason':729,732,741,742 'recipi':151 'recur':13,29,99,139,1227 'references/billing-agreements.md':1226 'references/express-checkout.md':1212 'references/ipn-handling.md':1217 'references/refund-workflows.md':1222 'refund':16,32,104,562,564,684,688,702,708,938,943,952,1010,1012,1015,1028,1223 'regular':804 'rel':927,1184 'relev':65 'reli':1284 'renew':144 'request':287,490,492 'request.form.to':517 'requests.exceptions.requestexception':1075 'requests.get':470,1037 'requests.post':345,402,440,615,844,909,1000 'requir':62,80,202,1373 'resourc':1211 'resources/implementation-playbook.md':82 'respons':344,401,439,469,614,843,908,999,1036 'response.json':360,409,445,475,851,916,1007,1042 'response.text':622 'rest':176 'result':1069,1073 'return':259,272,359,408,444,474,529,575,621,665,850,898,929,1006,1041,1072 'revers':570 'reversal/chargeback':723 'review':1366 'robust':1263 'safeti':1376 'sandbox':224,300,314,1125,1127,1130,1152,1155,1158,1277,1317 'scheme':812 'scope':56,1347 'sdk':163 'secret':233,236,298,306,308,358,767,870,962,1022,1131,1156 'self':294,326,366,413,450 'self.access':317,387,437,467 'self.base':309,333,376,423,458 'self.client':301,305,355,357 'self.get':319 'seller':1138 'send':147,600,668 'sequenc':805 'server':174,281 'server-sid':173,280 'set':97 'setup':827,834,1229 'side':161,175,282,1289 'skill':38,85,1339 'skill-paypal-integration' 'smart':164,208 'sole':1285 'source-sickn33' 'specif':1361 'specifi':1295 'start':204 'state':1327 'status':260,273,541,544,552,561,569,1209 'step':73,1196 'stop':1367 'str':399,816,987,1085,1099 'subscrib':857,891,894 'subscript':117,138,141,747,752,760,854,861,915,930,932,1239 'subscription.get':923 'subscription/recurring':744 'substitut':1357 'success':258,261,1379 'support':112 'system':705 'task':41,1343 'tenur':802 'test':1122,1132,1135,1143,1146,1198,1274,1363 'thorough':1275 'threshold':841 'time':127 'token':318,321,325,330,362,388,438,468,782,885,980,1035 'tool':53 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'total':807 'transact':262,538,661,1270,1313 'treat':1352 'tri':1068,1102 'true':826 'trust':1248 'txn':545,548,633,636,663,677,690,694,711,724,727,739 'type':351,382,432,539,546,549,776,803,879,974 'ui':185 'unit':393,797 'unrel':43 'updat':200,666 'url':310,331,334,346,374,377,403,421,424,441,456,459,471,607,613,617,768,771,845,871,874,899,904,910,919,935,963,966,1001,1023,1026,1038,1171,1173,1189 'urllib.parse':494 'urls/credentials':1320 'us':343 'usag':1101 'usd':369,820,833,991 'use':36,83,1124,1276,1337 'valid':69,599,1362 'valu':398,815,829,986,1329 'verif':75,201,482,531,605,1219,1251,1306 'verifi':212,519,525,580,584,591,594,619,623,1245,1301 'webhook':110,194,1236,1280,1322 'webhook-lik':193 'without':1250,1305 'workflow':17,33,939 'wrapper':1060 'wrong':1314 'yourdomain.com':901,906 'yourdomain.com/subscription/cancel':905 'yourdomain.com/subscription/success':900","prices":[{"id":"bc3c53c3-317a-4341-989f-97a35f781001","listingId":"b7b9daed-8e49-45d8-ae9b-cd7f7af5fe78","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:42:12.974Z"}],"sources":[{"listingId":"b7b9daed-8e49-45d8-ae9b-cd7f7af5fe78","source":"github","sourceId":"sickn33/antigravity-awesome-skills/paypal-integration","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/paypal-integration","isPrimary":false,"firstSeenAt":"2026-04-18T21:42:12.974Z","lastSeenAt":"2026-04-23T00:51:22.532Z"}],"details":{"listingId":"b7b9daed-8e49-45d8-ae9b-cd7f7af5fe78","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"paypal-integration","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34616,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"5bd1ebdda5012c26fb65d6d9eee047b47cd5c707","skill_md_path":"skills/paypal-integration/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/paypal-integration"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"paypal-integration","description":"Master PayPal payment integration including Express Checkout, IPN handling, recurring billing, and refund workflows."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/paypal-integration"},"updatedAt":"2026-04-23T00:51:22.532Z"}}