如何通过PayPal的API取消订阅?

12

您是否曾收到与“* 失败 ” / “ 配置文件 ID 无效 ”不同的回复?就我所发现的,您无法以这种方式取消“正常”创建的订阅(没有使用 CreateRecurringPaymentsProfile *)。在那里放置订阅 ID 并不能起到作用(对我来说是如此)。 - nssmart
2
订阅是通过网站支付标准的“订阅”按钮创建的。在2009年之前,订阅配置文件ID以S-XXXXXXXX开头。您无法通过任何API调用来管理这些订阅。在2009年之后,订阅配置文件ID以I-XXXXXX开头。您可以通过ManageRecurringPaymentsProfileStatus API调用取消这些订阅。我遇到了同样的问题,刚刚看到<a href="https://dev59.com/s2ox5IYBdhLWcg3wNRpj">Robert</a>的解决方案,它有效,您可以使用API取消标准网站订阅。 - Usman Zaheer
现在是2012年,我所有的订阅都以S-开头,但我无法使用取消方法。也许有人找到了解决办法? - Tomas
2个回答

16

你找到了简单的解决方案吗?我也在寻找。谢谢!

更新: 经过搜索,“ManageRecurringPaymentsProfileStatus”非常容易通过一个简单的POST请求来使用。

确保你的用户名、密码或签名不可见(换句话说,在服务器上执行此操作,而不是通过javascript或html posts在客户端上执行)。

下面是Python的一个简单实例。它有效,我现在每天都在使用它。

import urllib
from google.appengine.api import urlfetch

form_fields = {
        "METHOD": "ManageRecurringPaymentsProfileStatus",
        "PROFILEID": "xxx", # put your subscription ID here
        "ACTION": "cancel",
        "USER": "xxx", # Get USER, PWD, and SIGNATURE from your Paypal's account preferences
        "PWD": "xxx",
        "SIGNATURE": "xxx",
        "VERSION": "54.0"
}

api_url = 'https://api-3t.sandbox.paypal.com/nvp' # remove the sandbox part for production

form_data = urllib.urlencode(form_fields)

result = urlfetch.fetch(url=api_url,
                    payload=form_data,
                    method=urlfetch.POST,
                    headers={'Content-Type': 'application/x-www-form-urlencoded'})

响应是一个字符串,看起来像这样:

TIMESTAMP=2011%2d01%2d28T14%3a47%3a45Z&CORRELATIONID=148ebe1d25566&ACK=Failure&VERSION=54%2e0&BUILD=1704252&L_ERRORCODE0=11552&L_SHORTMESSAGE0=Invalid%20profile%20ID&L_LONGMESSAGE0=The%20profile%20ID%20is%20invalid&L_SEVERITYCODE0=Error

'ACK'字段指示“失败”或“成功”。

回答下面的评论时,请注意它确实使我能够取消通过动态创建的链接创建的订阅,例如:

<a href="https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_xclick-subscriptions&business=llcpro_1295263400_biz%40jeregle.com&item_name=Abonnement%20mensuel&a3=41.86&t3=M&p3=1&src=1&sra=1&currency_code=EUR&no_note=1&no_shipping=1&lc=FR&custom=xxxxx&notify_url=https%3A%2F%2Fyournotifyurl.com%2Fipn&charset=utf-8&country=FR&a1=0&t1=D&p1=31" target="_blank">Subscribe</a>

请注意,我根本不使用“modify”标志。


1
谢谢,Louis。我会尝试一下,但您能确认它适用于手动创建的订阅吗?请参见下面Vitaly的回答。 - Anthony
是的,它确实可以。我不知道你是如何创建订阅的,但我已经更新了我的答案,展示了我正在使用的方法。 - Louis LC
如果您仍然无法取消,请告诉我您的订阅ID格式(例如,特别是它们的第一个字符是什么)。同时,在调用ManageRecurringPaymentsProfileStatus时,请确保使用版本“54.0”。 - Louis LC
1
当您想通过“订阅”按钮取消订阅时,请将哪个订阅ID放入请求中?我尝试使用通过IPN收到的“subscr_id”(ID格式为I-<12chars>),但它始终无效。 - Xion
如果我只有一个令牌ID来识别自己怎么办?我没有用户名、密码或签名来识别自己。 - dhalfageme
显示剩余2条评论

0
我知道这是一个很旧的帖子,但是使用PayPal REST API取消订阅非常简单。虽然我对此还不太熟悉,但我已经能够弄清楚了。以下是我用来取消订阅的方法,这是用PHP编写的。
public function cancelSubscription(string $billingID, string $reason) : bool {
    $token = $this->getAccessToken()->access_token; // Authorization
    $url = $this->getCancelURI($billingID); // https://api-m.sandbox.paypal.com/v1/billing/subscriptions/{$billingID}/cancel
    
    $ch = curl_init($url);      
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt( $ch, CURLOPT_POST, 1 );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, "{
        \"reason\":\"{$reason}\"
    }");
    
    $headers = [];
    $headers[] = 'Content-Type: application/json';
    $headers[] = 'Authorization: Bearer ' . $token;
    curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    
    $result = curl_exec($ch);
    
    if(empty($result)) {
        // Logging results since it runs in background and no output is printed to the browser.
        $fh = fopen('debug_log.php','a+');
        fwrite($fh,PHP_EOL."Result True: {$result}".PHP_EOL);
        fclose($fh);
        return true;
    }
    else {
        // Logging results since it runs in background and no output is printed to the browser.
        $fh = fopen('debug_log.php','a+');
        fwrite($fh,PHP_EOL."Result False: {$result}".PHP_EOL);
        fclose($fh);
        return false;
    }
}

这就是它。根据接收到的内容,我会返回true或false,并根据返回值进行数据库更改。
希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接