All Products
Search
Document Center

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

Last Updated:Feb 09, 2024

In most cases, you must pay the fees that are generated by your buckets. However, you can enable pay-by-requester for your buckets to let authenticated requesters pay for the requests, data processing, and traffic generated when they access the data in the bucket. You only pay for other fees such as the storage fee. You can enable pay-by-requester to share your data in OSS without additional fees.

Scenarios

  • Share large datasets. For example, a research institute uploads a public dataset that includes postal code directories, reference data, geospatial information, or web crawling data 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. The header indicates 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 rules

When pay-by-requester is enabled, requesters are charged for one or more of the following billable items based on their request content: number of API requests, outbound traffic over the Internet, outbound origin traffic, Image Processing (IMG), video snapshots, data retrieval of IA or Archive objects, and advanced image compression. Bucket owners are charged for only object storage, tags, and transfer acceleration. For more information about each billable item, see Billing overview.

In the following scenarios, a request to a bucket for which pay-by-requester is enabled fails and OSS returns HTTP status code 403. The bucket owner is charged for the request.

  • The POST, GET, or HEAD request does not contain the x-oss-request-payer header.

  • The request fails to be authenticated.

  • The request is anonymous.

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 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\OssClient;
use OSS\Core\OssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that you specified the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables. 
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
// 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";

$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);

try {
    // Enable pay-by-requester for the bucket. 
    $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

For more information about how to use ossutil to configure pay-by-requester for a bucket, see request-payment (configure pay-by-requester).

Use the OSS RESTful API

If your program requires more custom options, you can call RESTful API operations. To call a RESTful API operation, you must include the signature calculation in your code. For more information, see PutBucketRequestPayment.