{"id":189,"library":"phonepe_sdk","title":"PhonePe Payment Gateway Python SDK","description":"Official PhonePe Payment Gateway Python SDK. NOT on PyPI — must install from PhonePe's private registry using a special pip command. TWO packages cause confusion: 'phonepe' on PyPI (1.0.1) is a community wrapper using old v1 API — NOT the official SDK. Official SDK is 'phonepe_sdk' from phonepe.mycloudrepo.io. Amount in paise (1 INR = 100 paise). Client must be initialized only ONCE — reinitializing raises PhonePeException. Mandatory status check polling after payment.","status":"active","version":"latest (from PhonePe registry)","language":"python","source_language":"en","source_url":"https://github.com/PhonePe/phonepe-pg-sdk-python","tags":["phonepe","payments","india","fintech","python","payment-gateway"],"install":[{"cmd":"pip install --index-url https://phonepe.mycloudrepo.io/public/repositories/phonepe-pg-sdk-python --extra-index-url https://pypi.org/simple phonepe_sdk","lang":"bash","label":"Python (official — from PhonePe registry, NOT PyPI)"}],"dependencies":[{"reason":"Required. Installed automatically.","package":"requests","optional":false}],"imports":[{"note":"Official SDK is NOT on PyPI. 'pip install phonepe' installs community wrapper using old v1 API. Official install requires --index-url flag pointing to PhonePe's registry.","wrong":"# Wrong: community package from PyPI — not official\nfrom phonepe import PhonePe\nphonepe = PhonePe('MERCHANT_ID', 'SALT', 'HOST', 'REDIRECT', 'WEBHOOK')\n\n# Wrong: pip install phonepe (wrong package)\n# Wrong: reinitializing client\nclient1 = StandardCheckoutClient(...)\nclient2 = StandardCheckoutClient(...)  # raises PhonePeException","symbol":"StandardCheckoutClient","correct":"from phonepe.sdk.pg.payments.v2.standard_checkout_client import StandardCheckoutClient\nfrom phonepe.sdk.pg.payments.v2.models.request.standard_checkout_pay_request import StandardCheckoutPayRequest\nfrom phonepe.sdk.pg.env import Env\nimport uuid\n\n# Initialize ONCE — reinitializing raises PhonePeException\nclient = StandardCheckoutClient(\n    client_id='<client_id>',\n    client_secret='<client_secret>',\n    client_version=1,\n    env=Env.SANDBOX  # or Env.PRODUCTION\n)\n\n# Create payment\norder_id = str(uuid.uuid4())\nrequest = StandardCheckoutPayRequest.build_request(\n    merchant_order_id=order_id,\n    amount=10000,  # 100 INR in paise\n    redirect_url='https://yourapp.com/callback'\n)\nresponse = client.pay(request)\nprint(response.redirect_url)  # redirect user here"}],"quickstart":{"code":"# Install from PhonePe registry (NOT PyPI):\n# pip install --index-url https://phonepe.mycloudrepo.io/public/repositories/phonepe-pg-sdk-python --extra-index-url https://pypi.org/simple phonepe_sdk\n\nfrom phonepe.sdk.pg.payments.v2.standard_checkout_client import StandardCheckoutClient\nfrom phonepe.sdk.pg.payments.v2.models.request.standard_checkout_pay_request import StandardCheckoutPayRequest\nfrom phonepe.sdk.pg.env import Env\nimport uuid\n\n# Initialize once at app startup\nclient = StandardCheckoutClient(\n    client_id='<client_id>',       # from PhonePe dashboard\n    client_secret='<client_secret>',\n    client_version=1,\n    env=Env.SANDBOX\n)\n\n# Create payment\norder_id = str(uuid.uuid4())\nrequest = StandardCheckoutPayRequest.build_request(\n    merchant_order_id=order_id,\n    amount=50000,  # 500 INR in paise\n    redirect_url=f'https://yourapp.com/callback?order_id={order_id}'\n)\nresponse = client.pay(request)\n\n# Redirect user to response.redirect_url\nprint('Redirect to:', response.redirect_url)\n\n# After redirect, check status (mandatory)\nstatus = client.get_order_status(merchant_order_id=order_id)\nprint('Payment state:', status.state)  # COMPLETED, FAILED, PENDING","lang":"python","description":"PhonePe Python SDK — payment creation and status check."},"warnings":[{"fix":"pip install --index-url https://phonepe.mycloudrepo.io/public/repositories/phonepe-pg-sdk-python --extra-index-url https://pypi.org/simple phonepe_sdk","message":"Official PhonePe SDK is NOT on PyPI. 'pip install phonepe_sdk' alone fails. Must use --index-url pointing to PhonePe's private registry.","severity":"breaking","affected_versions":"all"},{"fix":"Use official phonepe_sdk from PhonePe's registry, not 'pip install phonepe' from PyPI.","message":"'phonepe' on PyPI (1.0.1) is a community package using old PhonePe v1 API — NOT the official SDK. Using it risks API deprecation and lacks official support.","severity":"breaking","affected_versions":"all"},{"fix":"Initialize at app startup as a singleton. Use dependency injection or module-level variable.","message":"StandardCheckoutClient must be initialized ONLY ONCE per application. Reinitializing raises PhonePeException.","severity":"breaking","affected_versions":"all"},{"fix":"amount_in_paise = amount_in_inr * 100","message":"Amount is in paise (1 INR = 100 paise) — same as Razorpay. 500 INR = 50000 paise. Passing rupees directly will undercharge.","severity":"breaking","affected_versions":"all"},{"fix":"Always call client.get_order_status(merchant_order_id=order_id) after redirect to confirm payment state.","message":"Status check after payment is MANDATORY. PhonePe docs require polling get_order_status() after redirect — do not rely on redirect callback alone.","severity":"gotcha","affected_versions":"all"},{"fix":"Use Env.SANDBOX with sandbox credentials for testing. Switch to Env.PRODUCTION with live credentials for deployment.","message":"SANDBOX uses test credentials from PhonePe merchant dashboard. Sandbox and Production have different client_id/secret pairs.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure 'setuptools' is installed in your environment (e.g., by running `pip install setuptools`). In Docker environments based on minimal images like Alpine, you might need to explicitly add this to your Dockerfile.","message":"ModuleNotFoundError: No module named 'pkg_resources' occurs when the 'setuptools' package is not installed. This module is a dependency of 'apscheduler', which the PhonePe SDK utilizes.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:53:19.590Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Install the official SDK using the designated pip command: `pip install --index-url https://phonepe.mycloudrepo.io/public/repositories/phonepe-pg-sdk-python --extra-index-url https://pypi.org/simple phonepe_sdk`","cause":"The official PhonePe SDK (`phonepe_sdk`) was not installed correctly from PhonePe's private registry. Users often try `pip install phonepe_sdk` which fails, or `pip install phonepe` which installs an unofficial community wrapper from PyPI.","error":"ModuleNotFoundError: No module named 'phonepe_sdk'"},{"fix":"First, uninstall the incorrect PyPI package (`pip uninstall phonepe`). Then, ensure the official `phonepe_sdk` is installed using its specific `pip install` command. Finally, use the correct import path for the official SDK, e.g., `from phonepe.sdk.pg.payments.v2.standard_checkout_client import StandardCheckoutClient`.","cause":"This import statement targets the unofficial `phonepe` package available on PyPI, which is a community wrapper and not the official `phonepe_sdk` from PhonePe's private registry. Using this will lead to `AttributeError` when trying to access official SDK functionalities.","error":"import phonepe"},{"fix":"Ensure that the `PhonePePaymentClient` (or `StandardCheckoutClient`) is initialized only once and that the single instance is reused across all payment-related operations in your application.","cause":"The PhonePe SDK client was attempted to be initialized more than once within the application's lifecycle, which is explicitly prohibited by the SDK's design to prevent re-initialization issues.","error":"PhonePeException: Client already initialized"}],"ecosystem":"pypi","meta_description":null,"install_score":50,"install_tag":"draft","quickstart_score":30,"quickstart_tag":"draft","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"draft","tag_description":"notable install failures or slow imports","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.44,"mem_mb":17.5,"disk_size":"28.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1,"mem_mb":17.5,"disk_size":"29M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.84,"mem_mb":19.9,"disk_size":"31.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.52,"mem_mb":20.7,"disk_size":"32M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.34,"mem_mb":17.2,"disk_size":"28.2M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.18,"mem_mb":17.2,"disk_size":"29M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"draft","tag_description":"notable failures across runtimes","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}