All Products
Search
Document Center

Object Storage Service:Pay-by-requester

Last Updated:Apr 18, 2026

When you share large datasets, you can enable the Pay-by-requester mode for a bucket. This feature shifts data access costs, such as data transfer and request fees, to the data requester. The bucket owner is responsible only for storage fees and other fixed costs. When Pay-by-requester is enabled for a bucket, anonymous access is disabled, and all requests require authentication.

Applicability

Pay-by-requester can be enabled only for buckets that have a region attribute.

How it works

OSS processes requests based on the following logic:

  • If a request includes the x-oss-request-payer header, OSS authenticates the requester. If the authentication succeeds, the requester is charged for the data transfer and request fees.

  • If a request does not include the x-oss-request-payer header:

    • If the requester is the bucket owner, the request is processed normally and the bucket owner is charged for all fees.

    • If the requester is not the bucket owner, the request is rejected.

Bucket owner configuration

Step 1: Enable Pay-by-requester

  1. Log in to the OSS console.

  2. Click Buckets, and then click the name of the target bucket.

  3. In the left-side navigation pane, choose Bucket Settings > Pay-by-requester.

  4. On the Pay-by-requester page, turn on the Pay-by-requester switch.

  5. In the dialog box that appears, click OK.

Step 2: Grant requester access

Use a Bucket Policy to grant access permissions to the requester. Without these permissions, the requester cannot access the data.

  1. On the Buckets page, click the name of the target bucket.

  2. In the left-side navigation pane, choose Permission Control > Bucket Policy.

  3. On the Bucket Policy page, on the Add in GUI tab, click Authorize.

  4. In the Authorize panel, configure the policy. For Authorized User, select Other Accounts and enter the requester's Alibaba Cloud account ID or the ARN of the RAM role. The format is arn:sts::{RoleOwnerUid}:assumed-role/{RoleName}/{RoleSessionName}.

  5. Click OK.

Accessing data as a requester

As a requester, when you access a bucket with Pay-by-requester enabled, you must indicate in your request that you will pay the resulting fees.

Console

  1. Log in to the OSS console.

  2. In the left-side navigation pane, click the plus sign (+) next to Favorite Paths.

  3. In the Add Favorite Paths dialog box, configure the parameters as described in the following table.

    Parameter

    Description

    Adding method

    Select Add from other authorized buckets to add the authorized bucket to your favorite paths.

    Region

    Select the region where the authorized bucket resides.

    Bucket

    Enter the name of the authorized bucket.

    Pay-by-requester

    Select I understand and agree to confirm your agreement to pay. You can then access the specified resources in the file path. You will be billed for fees incurred from accessing the bucket, such as data transfer and request fees.

SDK

The following code provides an example on how to specify that third parties are charged when they access objects by calling the PutObject, GetObject, and DeleteObject operations. You can use the method to specify that third parties are charged when they perform read and write operations on objects by calling other API operations in the similar way.

When a third party performs an object operation, they must include the x-oss-request-payer:requester parameter in the HTTP header. Otherwise, the request fails.

Java

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.io.ByteArrayInputStream;

public class Demo {
    public static void main(String[] args) throws Exception{
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. For more information about the endpoints of other regions, see Regions and endpoints. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path. 
        String objectName = "exampledir/exampleobject.txt";
        Payer payer = Payer.Requester;
        // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou.
        String region = "cn-hangzhou";
        
        // Create an OSS Client instance. 
        // Call the shutdown method to release associated resources when the OSS Client is no longer in use.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();
        try {
            // Specify the payer when a third party calls the PutObject operation. 
            String content = "hello";
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
            putObjectRequest.setRequestPayer(payer);
            ossClient.putObject(putObjectRequest);

            // Specify the payer when a third party calls the GetObject operation. 
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
            getObjectRequest.setRequestPayer(payer);
            OSSObject ossObject = ossClient.getObject(getObjectRequest);
            ossObject.close();

            // Specify the payer when a third party calls the DeleteObject operation. 
            GenericRequest genericRequest = new GenericRequest(bucketName, objectName);
            genericRequest.setRequestPayer(payer);
            ossClient.deleteObject(genericRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

Python

# -*- coding: utf-8 -*-

import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.headers import OSS_REQUEST_PAYER

# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. 
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"

# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"

# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)

# Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
object_name = 'exampledir/exampleobject.txt'
headers = dict()
headers[OSS_REQUEST_PAYER] = "requester"

# Specify the x-oss-request-payer header in the request to upload the object. 
result = bucket.put_object(object_name, 'test-content', headers=headers)

# Specify the x-oss-request-payer header in the request to download the object. 
result = bucket.get_object(object_name, headers=headers)

# Specify the x-oss-request-payer header in the request to delete the object. 
result = bucket.delete_object(object_name, headers=headers);

Go

package main

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. 
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// Create an OSSClient instance. 
	// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint. 
	// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. Specify the actual region.
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// Specify the version of the signature algorithm.
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	payerClient, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		fmt.Println("New Error:", err)
		os.Exit(-1)
	}

	// Specify the name of the bucket. 
	payerBucket, err := payerClient.Bucket("examplebucket")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// If pay-by-requester is enabled, external requesters must set the oss.RequestPayer(oss.Requester) parameter to access authorized content. 
	// If pay-by-requester is not enabled, external requesters are not required to include the oss.RequestPayer(oss.Requester) parameter to access the authorized content. 

	// Upload an object. 
	// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
	key := "exampledir/exampleobject.txt"
	err = payerBucket.PutObject(key, strings.NewReader("objectValue"), oss.RequestPayer("requester"))
	if err != nil {
		fmt.Println("put Error:", err)
		os.Exit(-1)
	}

	// List all objects in the bucket. 
	lor, err := payerBucket.ListObjects(oss.RequestPayer(oss.Requester))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// Display the names of objects in the bucket. 
	for _, l := range lor.Objects {
		fmt.Println("the Key name is :", l.Key)
	}

	// Download the object. 
	body, err := payerBucket.GetObject(key, oss.RequestPayer(oss.Requester))
	if err != nil {
		fmt.Println("Get Error:", err)
		os.Exit(-1)
	}
	// You must close the obtained stream after the object is read. Otherwise, connection leaks may occur. Consequently, no connections are available and an exception occurs. 
	defer body.Close()

	// Read and display the obtained content. 
	data, err := io.ReadAll(body)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	fmt.Println("data:", string(data))

	// Delete the object. 
	err = payerBucket.DeleteObject(key, oss.RequestPayer(oss.Requester))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

Node.js

const OSS = require('ali-oss');
const bucket = 'bucket-name';
const payer = 'Requester';

const client = new OSS({
  // Set region to the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set region to oss-cn-hangzhou.
  region: 'yourregion',
  // Obtain access credentials from environment variables. Before running the sample code, make sure the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  authorizationV4: true,
  // Set bucket to your bucket name.
  bucket: 'yourBucketName',

});

async function main() {
  await put();
  await get();
  await del();
}

async function put() {
  const result = await client.putBucketRequestPayment(bucket, payer);
  console.log('putBucketRequestPayment:', result);
  // Specify the payer for the PutObject operation.
  const response = await client.put('fileName', path.normalize('D:\\localpath\\examplefile.txt'), {
    headers: {
      'x-oss-request-payer': 'requester'
    }
  });
  console.log('put:', response);
}

async function get() {
  const result = await client.putBucketRequestPayment(bucket, payer);
  console.log('putBucketRequestPayment:', result);
  // Specify the payer for the GetObject operation.
  const response = await client.get('fileName', {
    headers: {
      'x-oss-request-payer': 'requester'
    }
  });
  console.log('get:', response);
}

async function del() {
  const result = await client.putBucketRequestPayment(bucket, payer);
  console.log('putBucketRequestPayment:', result);
  // Specify the payer for the DeleteObject operation.
  const response = await client.delete('fileName', {
    headers: {
      'x-oss-request-payer': 'requester'
    }
  });
  console.log('delete:', response);
}

main();

C#

using System;
using System.IO;
using System.Text;
using Aliyun.OSS;
using Aliyun.OSS.Common;


namespace Samples
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
            var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. 
            var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
            var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
            // Specify the name of the bucket. Example: examplebucket. 
            var bucketName = "examplebucket";
            var objectName = "example.txt";
            var objectContent = "More than just cloud.";
            // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou.
            const string region = "cn-hangzhou";
            // Create a ClientConfiguration instance and modify parameters as required.
            var conf = new ClientConfiguration();
            // Use the signature algorithm V4.
            conf.SignatureVersion = SignatureVersion.V4;
            
            // Create an OSSClient instance.
            var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);

            try
            {
                byte[] binaryData = Encoding.ASCII.GetBytes(objectContent);
                MemoryStream requestContent = new MemoryStream(binaryData);
                // Specify the payer when a third party calls the PutObject operation. 
                var putRequest = new PutObjectRequest(bucketName, objectName, requestContent);
                putRequest.RequestPayer = RequestPayer.Requester;
                var result = client.PutObject(putRequest);

                // Specify the payer when a third party calls the GetObject operation. 
                var getRequest = new GetObjectRequest(bucketName, objectName);
                getRequest.RequestPayer = RequestPayer.Requester;
                var getResult = client.GetObject(getRequest);

                // Specify the payer when a third party calls the DeleteObject operation. 
                var delRequest = new DeleteObjectRequest(bucketName, objectName);
                delRequest.RequestPayer = RequestPayer.Requester;
                client.DeleteObject(delRequest);
            }
            catch (OssException ex)
            {
                Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
                    ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed with error info: {0}", ex.Message);
            }
        }
    }
}

PHP

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. 
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// Specify the name of the bucket. Example: examplebucket. 
$bucket= "examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
$object = "exampledir/exampleobject.txt";

// Enable pay-by-requester for the bucket. 
$options = array(
  OssClient::OSS_HEADERS => array(
  OssClient::OSS_REQUEST_PAYER => 'requester',
));

try {
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
        "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
        "region"=> "cn-hangzhou"
    );
    $ossClient = new OssClient($config);
    // Specify the payer when a third party calls the PutObject operation. 
    $content = "hello";
    $ossClient->putObject($bucket, $object, $content, $options);

    // Specify the payer when a third party calls the GetObject operation. 
    $ossClient->getObject($bucket, $object, $options);

    // Specify the payer when a third party calls the DeleteObject operation. 
    $ossClient->deleteObject($bucket, $object, $options);
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n"); 

C++


#include <alibabacloud/oss/OssClient.h>
#include <fstream>
using namespace AlibabaCloud::OSS;
int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set yourEndpoint to the endpoint of the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    
    /* Set yourRegion to the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the region to cn-hangzhou. */
    std::string Region = "yourRegion";
    
    /* Specify the name of the bucket that the requester wants to access. For example, examplebucket. */
    std::string BucketName = "examplebucket";    
    /* Specify the full path of the object that the requester wants to access. The full path cannot contain the bucket name. For example, exampledir/exampleobject.txt. */
    std::string ObjectName = "exampleobject.txt";
    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run this sample code, make sure that the requester's OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET are set as environment variables. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);    

    /* Set the pay-by-requester mode when you upload a file. */
    std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
    *content << "test cpp sdk";
    PutObjectRequest putrequest(BucketName, ObjectName, content);
    putrequest.setRequestPayer(RequestPayer::Requester);
    auto putoutcome = client.PutObject(putrequest);

    /* Set the pay-by-requester mode when you download a file to the local memory. */
    GetObjectRequest getrequest(BucketName, ObjectName);
    getrequest.setRequestPayer(RequestPayer::Requester);
    auto getoutcome = client.GetObject(getrequest);

    /* Set the pay-by-requester mode when you delete a file. */
    DeleteObjectRequest delrequest(BucketName, ObjectName);
    delrequest.setRequestPayer(RequestPayer::Requester);
    auto deloutcome = client.DeleteObject(delrequest);

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

ossutil

You must install ossutil before you can use it.

For example, to download an object using the cp command, specify the --request-payer=requester parameter.

ossutil cp oss://examplebucket/examplefile.txt  /localpath  --request-payer=requester

API

When making a direct REST API request, include the x-oss-request-payer: requester header in your request. Ensure this header is also included in the signature calculation. For more information about signature calculation, see Include a signature in the header.

GET /oss.jpg HTTP/1.1
Host: oss-example.oss-cn-hangzhou.aliyuncs.com
Date: Fri, 24 Feb 2012 06:38:30 GMT
Authorization: OSS4-HMAC-SHA256 Credential=LTAI********************/20250417/cn-hangzhou/oss/aliyun_v4_request,Signature=a7c3554c729d71929e0b84489addee6b2e8d5cb48595adfc51868c299c0c218e

Production considerations

  • Billing for access via a RAM role: When a requester accesses data by assuming an Alibaba Cloud RAM role, the account to which the RAM role belongs pays for the request.

    • Incorrect practice: Allow requesters to assume a RAM role from the bucket owner's account to gain access permissions. In this scenario, all requests are executed as the bucket owner, and the resulting request and data transfer fees are charged to the bucket owner. This practice does not transfer costs to the requester.

    • Correct practice: Grant access permissions directly to requesters using a Bucket Policy.

  • Presigned URL pitfalls:

    • Incorrect practice: The bucket owner uses their access credentials (an AccessKey pair or STS temporary credentials) to generate and share a presigned URL. In this case, requests are made as the bucket owner, and the bucket owner is charged the associated fees.

    • Correct practice: The requester uses their own access credentials (an AccessKey pair or STS temporary credentials) to generate a presigned URL and includes the x-oss-request-payer=requester parameter when generating the URL. For more information about how to calculate the signature, see Include a signature in the URL. When this URL is shared and used, the fees are charged to the requester who generated it.

  • Compatibility risks: Enabling Pay-by-requester can interfere with the anonymous access required for static website hosting, which may cause your website to become unavailable. We recommend that you deploy your website's frontend resources (HTML, CSS, and JS) and the data that requires Pay-by-requester in separate buckets.

Billing

Before Pay-by-requester is enabled for a bucket, all fees are paid by the bucket owner. After Pay-by-requester is enabled, the requester's account pays for the following billable items. The bucket owner's account continues to be charged for all other billable items. For a complete list of billable items, see OSS Pricing.

Fee

Billable item

Traffic fees

outbound traffic over the internet

origin traffic

Request fees

PUT requests

GET requests

Data processing

data retrieval from Infrequent Access

data retrieval from Archive Storage