When pay-by-requester is enabled for a bucket in Object Storage Service (OSS), requesters are charged for the request and traffic fees that are generated when the requesters access objects in the bucket. The bucket owner is charged only the storage fees of the objects. You can enable pay-by-requester to share your data in OSS without paying the fees that are generated when other users access your data.

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 ACL.
    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 ACL.
    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 under 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 within your Alibaba Cloud account with your partners. Otherwise, you are charged the request and traffic fees because the requesters use the RAM users within 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 POST, GET, and HEAD requests to the bucket. The value of the header is requester. This confirms that requesters understand that they are charged for the requests and traffic. Otherwise, the requests cannot be authenticated.
    • POST, GET, and HEAD requests must contain the x-oss-request-payer:requester header.
    • Requests that use signed URLs must contain the x-oss-request-payer=requester header.

    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

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, CDN back-to-origin traffic, Image Processing (IMG), video snapshots, data retrieval of IA or Archive objects, and advanced image compression. For more information about billable items, 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.

Use the OSS console

  1. Log on to the OSS console.
  2. In the left-side navigation pane, click Buckets. On the Buckets page, click the name of the desired bucket.
  3. In the 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.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;

public class Demo {
    public static void main(String[] args) {
        // 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";
        // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";

        // Create an OSSClient instance. 
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        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;

// Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
$accessKeyId = "yourAccessKeyId";
$accessKeySecret = "yourAccessKeySecret";
// In this example, the China (Hangzhou) region is used as the endpoint. 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',
  // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  accessKeyId: 'yourAccessKeyId',
  accessKeySecret: 'yourAccessKeySecret'
});

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.models import PAYER_BUCKETOWNER, PAYER_REQUESTER

# Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# Set yourEndpoint to 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 the pay-by-requester mode. 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;

// Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "yourEndpoint";
// Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS, because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
var accessKeyId = "yourAccessKeyId";
var accessKeySecret = "yourAccessKeySecret";
// Specify the bucket name. 
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() {
  // Create an OSSClient instance. 
  // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify the actual endpoint. 
  // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS, because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
  if err != nil {
    fmt.Println("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 OSS account information. */
    /* Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS, because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint 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;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, 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;
        ShutdownSdk();
        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 Enable pay-by-requester.

Use RESTful APIs

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.