Claude
Chat app · Skill upload
In Claude, open Customize → Skills and use Create skill to upload the ZIP. Skill availability depends on your plan and workspace settings.
Official Claude setup →Community skill · Free instruction package
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.
Community instruction package. Read the full workflow below, then choose your app in the setup guide. Package instructions and compatibility claims have not been individually verified; check dependencies and license before use.
CHOOSE YOUR AI APP
Choose your app below for setup instructions. Keep the complete downloaded folder together. Each package may need tools, dependencies or permissions that your app does not provide.
Chat app · Skill upload
In Claude, open Customize → Skills and use Create skill to upload the ZIP. Skill availability depends on your plan and workspace settings.
Official Claude setup →Chat app · Access varies
Where Skills is available, open Plugins → Skills → Create → Upload from your computer. Otherwise, copy the instructions into a chat and add your brief; this does not install a skill or include its supporting files.
Official ChatGPT setup →Agent · Project skills
Extract the complete skill folder into your project’s .agents/skills directory. Ask the agent to use the skill for your task.
.agents/skills/paypal-integration/SKILL.mdOfficial Google Antigravity setup →Code editor · Project skills
Extract the complete folder into .cursor/skills. Check the editor’s skill settings and ask the agent to use it.
.cursor/skills/paypal-integration/SKILL.mdOfficial Cursor setup →Coding agent · Project skills
Extract the complete folder into .claude/skills. Ask Claude to use the named skill, or use its slash command when available.
.claude/skills/paypal-integration/SKILL.mdOfficial Claude Code setup →For text-only workflows, you can also paste the instructions into an AI conversation. Copying text does not enable scripts, connect accounts or grant tool access. App subscriptions may cost extra. Logos identify the products; KuchhBhi is independent and is not endorsed by these companies.
Master PayPal payment integration including Express Checkout, IPN handling, recurring billing, and refund workflows.
resources/implementation-playbook.md.PayPal Checkout
PayPal Subscriptions
PayPal Payouts
Client-Side (JavaScript SDK)
Server-Side (REST API)
// Frontend - PayPal Smart Buttons
<div id="paypal-button-container"></div>
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID¤cy=USD"></script>
<script>
paypal.Buttons({
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '25.00'
}
}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
// Payment successful
console.log('Transaction completed by ' + details.payer.name.given_name);
// Send to backend for verification
fetch('/api/paypal/capture', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({orderID: data.orderID})
});
});
}
}).render('#paypal-button-container');
</script>
# Backend - Verify and capture order
from paypalrestsdk import Payment
import paypalrestsdk
paypalrestsdk.configure({
"mode": "sandbox", # or "live"
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
})
def capture_paypal_order(order_id):
"""Capture a PayPal order."""
payment = Payment.find(order_id)
if payment.execute({"payer_id": payment.payer.payer_info.payer_id}):
# Payment successful
return {
'status': 'success',
'transaction_id': payment.id,
'amount': payment.transactions[0].amount.total
}
else:
# Payment failed
return {
'status': 'failed',
'error': payment.error
}
import requests
import json
class PayPalClient:
def __init__(self, client_id, client_secret, mode='sandbox'):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = 'https://api-m.sandbox.paypal.com' if mode == 'sandbox' else 'https://api-m.paypal.com'
self.access_token = self.get_access_token()
def get_access_token(self):
"""Get OAuth access token."""
url = f"{self.base_url}/v1/oauth2/token"
headers = {"Accept": "application/json", "Accept-Language": "en_US"}
response = requests.post(
url,
headers=headers,
data={"grant_type": "client_credentials"},
auth=(self.client_id, self.client_secret)
)
return response.json()['access_token']
def create_order(self, amount, currency='USD'):
"""Create a PayPal order."""
url = f"{self.base_url}/v2/checkout/orders"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.access_token}"
}
payload = {
"intent": "CAPTURE",
"purchase_units": [{
"amount": {
"currency_code": currency,
"value": str(amount)
}
}]
}
response = requests.post(url, headers=headers, json=payload)
return response.json()
def capture_order(self, order_id):
"""Capture payment for an order."""
url = f"{self.base_url}/v2/checkout/orders/{order_id}/capture"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.access_token}"
}
response = requests.post(url, headers=headers)
return response.json()
def get_order_details(self, order_id):
"""Get order details."""
url = f"{self.base_url}/v2/checkout/orders/{order_id}"
headers = {
"Authorization": f"Bearer {self.access_token}"
}
response = requests.get(url, headers=headers)
return response.json()
from flask import Flask, request
import requests
from urllib.parse import parse_qs
app = Flask(__name__)
@app.route('/ipn', methods=['POST'])
def handle_ipn():
"""Handle PayPal IPN notifications."""
# Get IPN message
ipn_data = request.form.to_dict()
# Verify IPN with PayPal
if not verify_ipn(ipn_data):
return 'IPN verification failed', 400
# Process IPN based on transaction type
payment_status = ipn_data.get('payment_status')
txn_type = ipn_data.get('txn_type')
if payment_status == 'Completed':
handle_payment_completed(ipn_data)
elif payment_status == 'Refunded':
handle_refund(ipn_data)
elif payment_status == 'Reversed':
handle_chargeback(ipn_data)
return 'IPN processed', 200
def verify_ipn(ipn_data):
"""Verify IPN message authenticity."""
# Add 'cmd' parameter
verify_data = ipn_data.copy()
verify_data['cmd'] = '_notify-validate'
# Send back to PayPal for verification
paypal_url = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' # or production URL
response = requests.post(paypal_url, data=verify_data)
return response.text == 'VERIFIED'
def handle_payment_completed(ipn_data):
"""Process completed payment."""
txn_id = ipn_data.get('txn_id')
payer_email = ipn_data.get('payer_email')
mc_gross = ipn_data.get('mc_gross')
item_name = ipn_data.get('item_name')
# Check if already processed (prevent duplicates)
if is_transaction_processed(txn_id):
return
# Update database
# Send confirmation email
# Fulfill order
print(f"Payment completed: {txn_id}, Amount: ${mc_gross}")
def handle_refund(ipn_data):
"""Handle refund."""
parent_txn_id = ipn_data.get('parent_txn_id')
mc_gross = ipn_data.get('mc_gross')
# Process refund in your system
print(f"Refund processed: {parent_txn_id}, Amount: ${mc_gross}")
def handle_chargeback(ipn_data):
"""Handle payment reversal/chargeback."""
txn_id = ipn_data.get('txn_id')
reason_code = ipn_data.get('reason_code')
# Handle chargeback
print(f"Chargeback: {txn_id}, Reason: {reason_code}")
def create_subscription_plan(name, amount, interval='MONTH'):
"""Create a subscription plan."""
client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
url = f"{client.base_url}/v1/billing/plans"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {client.access_token}"
}
payload = {
"product_id": "PRODUCT_ID", # Create product first
"name": name,
"billing_cycles": [{
"frequency": {
"interval_unit": interval,
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 1,
"total_cycles": 0, # Infinite
"pricing_scheme": {
"fixed_price": {
"value": str(amount),
"currency_code": "USD"
}
}
}],
"payment_preferences": {
"auto_bill_outstanding": True,
"setup_fee": {
"value": "0",
"currency_code": "USD"
},
"setup_fee_failure_action": "CONTINUE",
"payment_failure_threshold": 3
}
}
response = requests.post(url, headers=headers, json=payload)
return response.json()
def create_subscription(plan_id, subscriber_email):
"""Create a subscription for a customer."""
client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
url = f"{client.base_url}/v1/billing/subscriptions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {client.access_token}"
}
payload = {
"plan_id": plan_id,
"subscriber": {
"email_address": subscriber_email
},
"application_context": {
"return_url": "https://yourdomain.com/subscription/success",
"cancel_url": "https://yourdomain.com/subscription/cancel"
}
}
response = requests.post(url, headers=headers, json=payload)
subscription = response.json()
# Get approval URL
for link in subscription.get('links', []):
if link['rel'] == 'approve':
return {
'subscription_id': subscription['id'],
'approval_url': link['href']
}
def create_refund(capture_id, amount=None, note=None):
"""Create a refund for a captured payment."""
client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
url = f"{client.base_url}/v2/payments/captures/{capture_id}/refund"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {client.access_token}"
}
payload = {}
if amount:
payload["amount"] = {
"value": str(amount),
"currency_code": "USD"
}
if note:
payload["note_to_payer"] = note
response = requests.post(url, headers=headers, json=payload)
return response.json()
def get_refund_details(refund_id):
"""Get refund details."""
client = PayPalClient(CLIENT_ID, CLIENT_SECRET)
url = f"{client.base_url}/v2/payments/refunds/{refund_id}"
headers = {
"Authorization": f"Bearer {client.access_token}"
}
response = requests.get(url, headers=headers)
return response.json()
class PayPalError(Exception):
"""Custom PayPal error."""
pass
def handle_paypal_api_call(api_function):
"""Wrapper for PayPal API calls with error handling."""
try:
result = api_function()
return result
except requests.exceptions.RequestException as e:
# Network error
raise PayPalError(f"Network error: {str(e)}")
except Exception as e:
# Other errors
raise PayPalError(f"PayPal API error: {str(e)}")
# Usage
try:
order = handle_paypal_api_call(lambda: client.create_order(25.00))
except PayPalError as e:
# Handle error appropriately
log_error(e)
# Use sandbox credentials
SANDBOX_CLIENT_ID = "..."
SANDBOX_SECRET = "..."
# Test accounts
# Create test buyer and seller accounts at developer.paypal.com
def test_payment_flow():
"""Test complete payment flow."""
client = PayPalClient(SANDBOX_CLIENT_ID, SANDBOX_SECRET, mode='sandbox')
# Create order
order = client.create_order(10.00)
assert 'id' in order
# Get approval URL
approval_url = next((link['href'] for link in order['links'] if link['rel'] == 'approve'), None)
assert approval_url is not None
# After approval (manual step with test account)
# Capture order
# captured = client.capture_order(order['id'])
# assert captured['status'] == 'COMPLETED'
The instruction package is free to download. Your AI app, model usage, connected services and third-party assets may have separate costs.
It is a set of instructions for a compatible AI assistant. It does not run by itself, connect accounts or install an MCP server.
Check that the named folder contains SKILL.md directly, not a second nested ZIP folder. Confirm that your editor supports skills and that its current settings allow this location. See the official documentation below.