Core Pi SDK

The Pi SDK provides all of the functionality for your app to operate in the Pi Ecosystem. This page presumes that pi-sdk.js has been loaded into the browser.

This guide demonstrates how to integrate the Pi SDK into many application frameworks. This example shows how to initialize the Pi SDK, authenticate a Pioneer, and create a payment request inside a Pi app.

The pi-sdk-js package is part of the “Ten Minutes to Transactions” effort described in this video.

If you, or your GenAI agent, are planning to use the Pi SDK modules in this documentation for your app, it is highly suggested that you use this package rather than implement transaction processing by hand with the core Pi SDK. The three way handshake between client, server, and the Pi servers required is provded for you.

Note: Pi SDK authentication and payment features require the application to run inside the Pi Browser.

  • Initialization & Authentication
  • Payment Flow

Pi SDK Instance

All methods below are called via window.Pi (not statically).


Core Methods

Initialization & Authentication

.init(options)

  • Purpose: Initialize the SDK, typically called once application loads.
  • Signature:
    window.Pi.init({ version: '2.0', sandbox?: boolean })
    
  • Parameters:
    • version (string, required) – SDK protocol version
    • sandbox (boolean, optional)

.authenticate(scopes, onIncompletePaymentFound)

  • Purpose: Requests user authentication via Pi Browser, and checks for incomplete payments.
  • Signature:
    window.Pi.authenticate([
        'payments',           // Required for payment flows
        'username',           // Get user info
        'roles', 'wallet_address', ... // Additional scopes
      ], onIncompletePaymentFound)
      .then(({ user, accessToken }) => { ... });
    
  • Parameters:
    • scopes (array of strings): Permissions to request (at least 'payments', 'username')
    • onIncompletePaymentFound (function, optional): Callback invoked if any unfinished payment should be handled
  • Returns: Promise resolving to { user, accessToken }

Important: You must successfully authenticate the user before performing any user-related actions (for example, reading their info or initiating a payment). The first time a user authenticates, Pi Browser shows a consent dialog asking them to share their data with your app.


Payment Flow

.createPayment(paymentData, callbacks)

  • Purpose: Initiates a Pi payment by sending a payment request from the current user to your app’s account.
    • What the user sees: A Pi Wallet modal opens on top of your app, prompting the user to review the payment details, sign the transaction, and submit it to the Pi Blockchain (or cancel the request).
  • Signature:
    window.Pi.createPayment(paymentData, {
      onReadyForServerApproval: (paymentId) => { ... },
      onReadyForServerCompletion: (paymentId, txid) => { ... },
      onCancel: (paymentId) => { ... },
      onError: (error, paymentData) => { ... }
    });
    
  • Parameters:
    • paymentData (object): Payment details, e.g. { amount, memo, metadata }
    • callbacks (object): Required handler functions (see above)

Looking for App-to-User (A2U) payouts? Pi.createPayment covers User-to-App (U2A) flows. For payments from your app to users (A2U), use the Platform API from your backend. See Advanced Payments for details.

Callback Functions

  • onReadyForServerApproval(paymentId) – Called when payment is ready for backend approval
  • onReadyForServerCompletion(paymentId, txid) – Called when network waits for backend to mark complete
  • onCancel(paymentId) – Payment canceled by user
  • onError(error, paymentData) – Error in payment process
  • onIncompletePaymentFound(paymentDTO) – (from .authenticate) handle unfinished payment

General Usage Example

Important: The <script> tag below is required in every Pi app’s index.html. The Pi Browser does not automatically inject window.Pi — you must load the SDK and call Pi.init() before any other Pi SDK calls.

<!-- index.html — REQUIRED -->
<script src="https://sdk.minepi.com/pi-sdk.js"></script>
// Step 1: Initialize (call once on app load, before authenticate or createPayment)
window.Pi.init({ version: "2.0", sandbox: true }); // sandbox: false in production

// Step 2: Authenticate — always send accessToken to your backend for verification
window.Pi.authenticate(["payments", "username"], function onIncompletePaymentFound(payment) {
  // Handle an incomplete payment found by Pi (see Payment Flow below)
  fetch("/api/payment/incomplete", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ paymentId: payment.identifier }),
  });
}).then(({ user, accessToken }) => {
  // Step 3: Verify accessToken server-side — never trust client-side user data alone
  return fetch("/api/auth/verify", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ accessToken }),
  });
  // Backend: GET https://api.minepi.com/v2/me   Authorization: Bearer <accessToken>
}).then(() => {
  // Step 4: Create a payment — only grant features after onReadyForServerCompletion
  window.Pi.createPayment(
    { amount: 0.02, memo: "Pi Example", metadata: { order_id: 42 } },
    {
      onReadyForServerApproval: (paymentId) => {
        // Phase I: Your server calls POST /payments/{paymentId}/approve on Pi Platform API
        fetch("/api/payment/approve", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ paymentId }),
        });
      },
      onReadyForServerCompletion: (paymentId, txid) => {
        // Phase III: Your server calls POST /payments/{paymentId}/complete on Pi Platform API
        // ONLY deliver the purchased feature/goods after this callback succeeds on the server
        fetch("/api/payment/complete", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ paymentId, txid }),
        }).then(res => {
          if (res.ok) {
            // Safe to deliver feature here
          }
        });
      },
      onCancel: (paymentId) => {
        console.log("Canceled", paymentId);
        // Do NOT grant any feature on cancel
      },
      onError: (error) => {
        console.error(error);
      },
    },
  );
});

Common Mistake: Do not grant purchased features when onReadyForServerApproval fires or when the payment modal closes. Always wait for onReadyForServerCompletion to complete on the server. See Common Mistakes for more details.


Access Point Summary Table

Property / Function Description / Methods
window.Pi Main SDK instance
.init Initialize SDK
.authenticate User login and canonical Pi integration
.createPayment Start payment flow
.Ads Ad management (isAdReady, requestAd, showAd)
.openShareDialog Open Pi share dialog
.openConversation Pi chat/conversation integration
.nativeFeaturesList List supported native features
.requestPermission Request native OS permission
.copyText Copy text to clipboard
.openUrlInSystemBrowser Open link in external browser

Functionality is inferred from SDK patterns, public documentation, and code inspection. Actual API may differ slightly depending on SDK version. Not all methods will be present/documented if not supported by a particular build.

For question about specific methods, advanced usage, or backend integration, see core SDK documentation or contact Pi Network developer support.