All Products
Search
Document Center

Object Storage Service:Enable pay-by-requester to let requesters pay for traffic, requests, and data processing

Last Updated:Apr 18, 2024

By default, the owner of a bucket pays all fees that are generated for the bucket. However, you can enable pay-by-requester for a bucket to let authenticated requesters pay for the requests, data processing, and traffic generated when they access the data in the bucket. You pay only other fees, such as storage fees. You can enable pay-by-requester to share your data in a bucket without paying fees that are generated by access to the data by other requesters.

Scenarios

  • Share large datasets. For example, a research institute uploads a public dataset that includes postal code directories, reference data, geospatial information, or data collected by web crawlers to an OSS bucket and wants to make the dataset accessible to all customers. In addition, the research institute wants requesters to pay the request and traffic fees that are generated by their access to the dataset.

    To meet this business requirement, the research institute can configure the following settings in OSS:

    1. Set the access control list (ACL) of the bucket in which the public dataset is stored to public-read. For more information, see Bucket ACLs.

    2. Enable pay-by-requester for the bucket.

  • Deliver production data to your customers or partners. For example, you want to make your production data in OSS accessible to your partners and let your partners pay the request and traffic fees when they download the production data.

    To meet this business requirement, you can configure the following settings in OSS:

    1. Set the ACL of the bucket in which the production data is stored to private. For more information, see Bucket ACLs.

    2. Enable pay-by-requester for the bucket.

    3. Use bucket policies to grant your partners permissions to access the production data in the bucket. For more information, see Tutorial: Authorize a RAM user in another Alibaba Cloud account by adding a bucket policy.

    Important

    Make sure that you grant permissions to the RAM users of your partners to access the production data in the bucket. For the purposes of pay-by-requester, do not share the AccessKey pairs of RAM users of your Alibaba Cloud account with your partners. Otherwise, you are charged the request and traffic fees because the requesters use the RAM users of your Alibaba Cloud account to access the production data.

Request methods

  • Requests from anonymous users are not allowed

    If you enable pay-by-requester for a bucket, anonymous users cannot access the bucket. Requesters must provide authentication information. OSS can identify requesters based on the given information. This way, the requesters are charged request and traffic fees.

    If a requester uses a RAM user of an Alibaba Cloud account to request data, the Alibaba Cloud account to which the RAM user belongs is charged for the requests sent by the requester and the generated traffic.

  • Requests must contain the x-oss-request-payer header

    If you enable pay-by-requester for a bucket, requesters must specify the x-oss-request-payer header in the requests to the bucket and set the value of the header to requester. This confirms that the requesters understand that they are charged for the requests and traffic. Otherwise, the requests cannot be authenticated.

    Bucket owners do not need to contain the x-oss-request-payer header in the requests that are sent to access their buckets. Bucket owners are charged for their own requests and generated traffic.

Billing

Before pay-by-requester is enabled for a bucket, the owner of the bucket pays all fees associated with the bucket. After pay-by-requester is enabled for the bucket, billable items that apply to the bucket owner are different from those before pay-by-requester is enabled. The following table lists billable items on bucket owners and requesters after pay-by-requester is enabled.

Billing category

Billable item

Payer

Storage

Storage usage of Standard LRS objects

Bucket owner

Storage usage of Standard ZRS objects

Bucket owner

Storage usage of IA LRS objects

Bucket owner

Storage usage of IA ZRS objects

Bucket owner

Storage usage of Archive LRS objects

Bucket owner

Storage usage of Archive ZRS objects

Bucket owner

Storage usage of Cold Archive LRS objects

Bucket owner

Storage usage of Deep Cold Archive LRS objects

Bucket owner

Storage usage of IA LRS objects that are stored for less than the minimum storage duration

Bucket owner

Storage usage of Archive LRS objects that are stored for less than the minimum storage duration

Bucket owner

Storage usage of Archive ZRS objects that are stored for less than the minimum storage duration

Bucket owner

Storage usage of Cold Archive objects that are stored for less than the minimum storage duration

Bucket owner

Storage usage of Deep Cold Archive objects that are stored for less than the minimum storage duration

Bucket owner

Traffic

Outbound traffic over the Internet

Requester

Inbound traffic over the Internet

Free of charge

Outbound traffic over the internal network

Free of charge

Inbound traffic over the internal network

Free of charge

Origin traffic

Requester

CRR traffic

Bucket owner

API operation calling*1

Number of PUT requests

Requester

Number of GET requests

Requester

Data retrieval requests

Bucket owner

Scanned data capacity for SelectObject

Bucket owner

Retrieval of IA objects

Requester

Retrieval of Archive objects

Requester

Retrieval of Archived objects for which real-time access is enabled

Bucket owner

Retrieval of Cold Archive objects

Bucket owner

Retrieval of Deep Cold Archive objects

Bucket owner

Object tagging

Object tagging

Bucket owner

Transfer acceleration

AccM2MIn

Bucket owner

AccM2MOut

Bucket owner

AccM2OIn

Bucket owner

AccM2OOut

Bucket owner

AccO2MIn

Bucket owner

AccO2MOut

Bucket owner

AccO2OIn

Bucket owner

AccO2OOut

Bucket owner

Temporary storage

Temporary replica (LRS) capacity

Bucket owner

DDoS protection

Reserved OSS DDoS protection instances

Bucket owner

Remaining duration of OSS DDoS protection instances released within the minimum usage duration

Bucket owner

Traffic protected by OSS DDoS protection instances

Bucket owner

API requests protected by OSS DDoS protection instances

Bucket owner

Data indexing

Metadata management

In public preview and free of charge

Bucket query

In public preview and free of charge

RTC traffic fees

RTC-enabled CRR tasks

Bucket owner

Note

*1 If requesters do not include the x-oss-request-payer:requester header in the GET, HEAD, or POST request, the bucket owner is charged for PUT and GET requests.

Procedure

Use the OSS console

  1. Log on to the OSS console.

  2. In the left-side navigation pane, click Buckets. On the Buckets page, find and click the desired bucket.

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

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

  5. In the message that appears, click OK.

    Note

    If you want to disable pay-by-requester, turn off Pay-by-requester and then click OK in the message that appears.

Use OSS SDKs

The following sample code provides examples on how to configure pay-by-requester for a bucket by using OSS SDKs for common programming languages. For more information about how to configure pay-by-requester for a bucket by using OSS SDKs for other programming languages, see Overview.

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.model.*;

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. 
        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";

        // Create an OSSClient instance. 
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
        try {
            // Enable pay-by-requester for the bucket. 
            Payer payer = Payer.Requester;
            ossClient.setBucketRequestPayment(bucketName, payer);
        } 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();
            }
        }
    }
}
<?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 configured. 
$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";

try {
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
    $ossClient->putBucketRequestPayment($bucket, "Requester");
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n");
const OSS = require('ali-oss')

const client = new OSS({
  // 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 oss-cn-hangzhou. 
  region: 'yourregion',
  // Obtain access credentials from environment variables. Before you run the sample code, make sure that you have configured environment variables OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET. 
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET
});

async function setBucketRequestPayment(bucket, Payer) {
  try {
    // Specify the name of the bucket for which you want to enable pay-by-requester. 
    // Set Payer to Requester or BucketOwner. 
    // If Payer is set to Requester, pay-by-requester is enabled for the bucket. The requester is charged the traffic and request fees that are generated when the requester reads data in the bucket. 
    // If Payer is set to BucketOwner, pay-by-requester is disabled for the bucket. This is the default configuration for the bucket. In this case, the bucket owner is charged the generated request fees. 
    const result = await client.putBucketRequestPayment(bucket, Payer);
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

setBucketRequestPayment('bucketName', 'Requester')
# -*- coding: utf-8 -*-

import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import PAYER_BUCKETOWNER, PAYER_REQUESTER

# 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. 
auth = oss2.ProviderAuth(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. 
# Specify the name of the bucket. Example: examplebucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

# Enable pay-by-requester for the bucket. The default request payment mode is PAYER_BUCKETOWNER. 
result = bucket.put_bucket_request_payment(PAYER_REQUESTER)

print("http respon status: ", result.status)
using Aliyun.OSS;
using Aliyun.OSS.Common;

// 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 = "yourEndpoint";
// 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. 
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// Specify the name of the bucket. 
var bucketName = "examplebucket";

// Create an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    // Enable pay-by-requester for the bucket. 
    var request = new SetBucketRequestPaymentRequest(bucketName, RequestPayer.Requester);
    client.SetBucketRequestPayment(request);
    Console.WriteLine("Set bucket:{0} RequestPayment succeeded ", bucketName);
}
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);
}
package main

import (
	"fmt"
	"os"

	"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 configured. 
	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. 
	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		fmt.Println("New Error:", err)
		os.Exit(-1)
	}

	// Initialize the pay-by-requester mode. 
	reqPayConf := oss.RequestPaymentConfiguration{
		Payer: "Requester",
	}

	// Enable pay-by-requester for the bucket. 
	err = client.SetBucketRequestPayment("<yourBucketName>", reqPayConf)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize information about the account that is used to access OSS. */
    
    /* 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. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";

    /* Initialize resources such as network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    /* 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. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);

    /* Enable pay-by-requester for the bucket. */
    SetBucketRequestPaymentRequest request(BucketName);
    request.setRequestPayer(RequestPayer::Requester);

    auto outcome = client.SetBucketRequestPayment(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "SetBucketRequestPayment fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

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

Use ossutil

You can configure pay-by-requester for a bucket by using ossutil. For more information, see request-payment.

Use the OSS API

If your business requires a high level of customization, you can directly call RESTful APIs. To directly call an API, you must include the signature calculation in your code. For more information, see PutBucketRequestPayment.